chicken_dy/Assets/WX-WASM-SDK/Editor/TextureEditor/WXTextureEditorWindow.cs

496 lines
20 KiB
C#
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using UnityEngine;
using System.Collections;
using UnityEditor;
using System.IO;
using System.Collections.Generic;
using LitJson;
using System.Text;
using System.Linq;
using System;
namespace WeChatWASM
{
public class WXReplaceTextureData
{
public string path;
public int width;
public int height;
}
public class WXBundlePicDepsData
{
public string bundlePath;
public List<WXReplaceTextureData> pics;
public bool isCached;
}
public class WXFileCachedData
{
public string filePath;
public string md5;
}
public class JSTextureTaskConf
{
public string dst;
public string dataPath;
public bool useDXT5;
public List<WXReplaceTextureData> textureList;
}
public class JSTextureData {
public string p;
public int w;
public int h;
}
public class WXTextureFileCacheScriptObject
{
public int Version;
public DateTime UpdateTime;
public int CostTimeInSeconds;
public List<WXFileCachedData> cachedDatas = new List<WXFileCachedData>();
}
public class WXTextureReplacerScriptObject
{
public int Version;
public DateTime UpdateTime;
public List<WXBundlePicDepsData> bundlePicDeps = new List<WXBundlePicDepsData>();
}
public class WXTextureEditorWindow : EditorWindow
{
public static WXEditorScriptObject miniGameConf;
[MenuItem("微信小游戏 / 包体瘦身--压缩纹理")]
public static void Open()
{
miniGameConf = UnityUtil.GetEditorConf();
var win = GetWindow(typeof(WXTextureEditorWindow), false, "包体瘦身--压缩纹理", true);//创建窗口
win.minSize = new Vector2(600, 380);
win.maxSize = new Vector2(600, 380);
win.Show();
}
public static void Log(string type,string msg) {
if (type == "Error") {
UnityEngine.Debug.LogError(msg);
} else if (type == "Log") {
UnityEngine.Debug.Log(msg);
} else if (type == "Warn") {
UnityEngine.Debug.LogWarning(msg);
}
}
private static WXTextureReplacerScriptObject GetTextureEditorCacheConf()
{
var BundlePicsFilePath = Path.Combine(GetDestDir(), "BundlePicsFile.json");
string BundlePicsFileJson = "";
if (File.Exists(BundlePicsFilePath))
{
using (FileStream fileStream = new FileStream(BundlePicsFilePath, FileMode.Open, FileAccess.Read))
{
using (StreamReader reader = new StreamReader(fileStream))
{
BundlePicsFileJson = reader.ReadToEnd();
}
}
}
WXTextureReplacerScriptObject wXTextureReplacerScriptObject = JsonMapper.ToObject<WXTextureReplacerScriptObject>(BundlePicsFileJson);
Dictionary<string, List<WXReplaceTextureData>> cacheMap = new Dictionary<string, List<WXReplaceTextureData>>();
if (wXTextureReplacerScriptObject == null) wXTextureReplacerScriptObject = new WXTextureReplacerScriptObject();
if (wXTextureReplacerScriptObject.bundlePicDeps == null) wXTextureReplacerScriptObject.bundlePicDeps = new List<WXBundlePicDepsData>();
return wXTextureReplacerScriptObject;
}
public static void CreateJSTask()
{
WXTextureReplacerScriptObject wXTextureReplacerScriptObject = GetTextureEditorCacheConf();
List<WXReplaceTextureData> list = new List<WXReplaceTextureData>();
Dictionary<string, List<WXReplaceTextureData>> cacheMap = new Dictionary<string, List<WXReplaceTextureData>>();
foreach (var item in wXTextureReplacerScriptObject.bundlePicDeps)
{
if(item.pics == null)
{
continue;
}
list = list.Union(item.pics).ToList();
cacheMap.Add(item.bundlePath, item.pics);
}
var conf = new JSTextureTaskConf()
{
dst = GetDestDir(),
dataPath = Application.dataPath,
useDXT5 = miniGameConf.CompressTexture.useDXT5,
textureList = list,
};
File.WriteAllText(Application.dataPath + "/WX-WASM-SDK/Editor/Node/conf.js", "module.exports = " + JsonMapper.ToJson(conf));
UnityEngine.Debug.LogError($"最后一步请安装 Nodejs 然后进入{Application.dataPath}/WX-WASM-SDK/Editor/Node 目录用命令行,执行 node compress_astc_only.js (开发阶段使用) 或 node compress_all.js上线时候使用 命令来生成纹理。");
ModifiyJsFile(cacheMap);
}
public static void ModifiyJsFile(Dictionary<string, List<WXReplaceTextureData>> picDeps) {
//修改使用纹理dxt
string content = File.ReadAllText(Path.Combine(Application.dataPath, "WX-WASM-SDK", "wechat-default", "unity-sdk", "texture.js"), Encoding.UTF8);
content = content.Replace("\"$UseDXT5$\"", miniGameConf.CompressTexture.useDXT5 ? "true" : "false");
File.WriteAllText(Path.Combine(miniGameConf.ProjectConf.DST, "minigame", "unity-sdk", "texture.js"), content, Encoding.UTF8);
Dictionary<string, List<JSTextureData>> picDepsShort = new Dictionary<string, List<JSTextureData>>();
foreach(var item in picDeps)
{
if (item.Key != "unity_default_resources")
{
var list = new List<JSTextureData>();
if (item.Value == null) {
continue;
}
foreach (var data in item.Value) {
list.Add(new JSTextureData()
{
h = data.height,
w = data.width,
p = data.path
});
}
picDepsShort.Add(item.Key,list);
}
}
var textureConfigPath = Path.Combine(miniGameConf.ProjectConf.DST, "minigame", "texture-config.js");
if (miniGameConf.CompressTexture.parallelWithBundle)
{
File.WriteAllText(textureConfigPath, "GameGlobal.USED_TEXTURE_COMPRESSION=true;GameGlobal.TEXTURE_PARALLEL_BUNDLE=true;GameGlobal.TEXTURE_BUNDLES = " + JsonMapper.ToJson(picDepsShort) , Encoding.UTF8);
}
else
{
File.WriteAllText(textureConfigPath, "GameGlobal.USED_TEXTURE_COMPRESSION=true;GameGlobal.TEXTURE_PARALLEL_BUNDLE=false;GameGlobal.TEXTURE_BUNDLES = ''", Encoding.UTF8);
}
}
public static string GetDestDir() {
var dstDir = miniGameConf.ProjectConf.DST + "/webgl-min";
if (!string.IsNullOrEmpty(miniGameConf.CompressTexture.dstMinDir))
{
dstDir = miniGameConf.CompressTexture.dstMinDir;
}
return dstDir;
}
public static void ReplaceBundle()
{
if (string.IsNullOrEmpty(miniGameConf.CompressTexture.bundleSuffix)) {
UnityEngine.Debug.LogError("bundle后缀不能为空");
return;
}
if (string.IsNullOrEmpty(miniGameConf.ProjectConf.DST)) {
UnityEngine.Debug.LogError("请先转换为小游戏!");
return;
}
if (!File.Exists(miniGameConf.ProjectConf.DST+"/webgl/index.html")) {
UnityEngine.Debug.LogError("请先转换为小游戏并确保导出目录下存在webgl目录");
return;
}
UnityEngine.Debug.Log("Start! 【" + System.DateTime.Now.ToString("T") + "】");
var dstDir = GetDestDir();
var dstTexturePath = dstDir + "/Assets/Textures";
var sourceDir = miniGameConf.ProjectConf.DST + "/webgl";
var path = "";
var exePath = Path.Combine(Application.dataPath, "WX-WASM-SDK/Editor/TextureEditor/Release/WXTextureMin.exe");
var classDataPath = Path.Combine(Application.dataPath, "WX-WASM-SDK/Editor/TextureEditor/classdata.tpk");
var bundlePathArg = string.IsNullOrEmpty(miniGameConf.CompressTexture.bundleDir) ? "" : $" -bd {miniGameConf.CompressTexture.bundleDir}";
#if UNITY_EDITOR_OSX
var monoPath = Path.Combine(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "Unity.app/Contents/MonoBleedingEdge/bin/mono");
Path.Combine(Application.dataPath, "WX-WASM-SDK/Editor/TextureEditor/Release/WXTextureMin.exe");
WeChatWASM.UnityUtil.RunCmd(monoPath, string.Format($" {exePath} -b {miniGameConf.CompressTexture.bundleSuffix} " +
$" -d {dstDir}" +
$" -dt {dstTexturePath}" +
$" -s {sourceDir}" +
$" -c {classDataPath}" +
$" {bundlePathArg}"), path,
(current, total, extInfo) => {
EditorUtility.DisplayProgressBar($"TextureMin Bundle处理中当前:{current},总共:{total}", $"Handling:{extInfo}", current * 1.0f / total);
});
EditorUtility.ClearProgressBar();
#else
exePath = Path.Combine(Application.dataPath, "WX-WASM-SDK/Editor/TextureEditor/Release/WXTextureMin.exe");
WeChatWASM.UnityUtil.RunCmd(exePath, string.Format($" -b {miniGameConf.CompressTexture.bundleSuffix} " +
$" -d {dstDir}" +
$" -dt {dstTexturePath}" +
$" -s {sourceDir}" +
$" -c {classDataPath}" +
$" {bundlePathArg}"), path,
(current, total, extInfo) => {
EditorUtility.DisplayProgressBar($"TextureMin Bundle处理中当前:{current},总共:{total}", $"Handling:{extInfo}", current * 1.0f / total);
});
EditorUtility.ClearProgressBar();
#endif
OnReplaceEnd();
}
private static void OnReplaceEnd() {
CreateJSTask();
if (miniGameConf.ProjectConf.assetLoadType == 1)
{
DirectoryInfo TheFolder = new DirectoryInfo(miniGameConf.ProjectConf.DST + "/minigame/data-package/");
var dstDataFiles = TheFolder.GetFiles("*.txt");
if (dstDataFiles.Length != 1)
{
Debug.LogError("目录minigame/data-package/无法找到data首资源文件, 无法进行首资源包替换");
return;
}
var dstDataFile = dstDataFiles[0].FullName;
var sourceDataFile = Path.Combine(GetDestDir(), Path.GetFileName(dstDataFile));
if (!File.Exists(sourceDataFile))
{
Debug.LogError($"sourceDataFile not exist {sourceDataFile}");
return;
}
File.Delete(dstDataFile);
File.Copy(sourceDataFile, dstDataFile);
}
// 替换资源文件后更新文件大小
// var info = new FileInfo(sourceDataFile);
// var oldSize = WXEditorWindow.GetWindow<WXEditorWindow>().dataFileSize;
// var newSize = info.Length.ToString();
// string[] files = {"game.js"};
// Rule[] rules = {
// new Rule() {
// old="DATA_FILE_SIZE: \"" + oldSize + "\"",
// newStr="DATA_FILE_SIZE: \"" + newSize + "\""
// }
// };
// WXEditorWindow.GetWindow<WXEditorWindow>().ReplaceFileContent(files, rules);
UnityEngine.Debug.Log("Done! 【" + System.DateTime.Now.ToString("T") + "】");
}
private void OnDisable()
{
EditorUtility.SetDirty(miniGameConf);
}
private void OnEnable()
{
miniGameConf = UnityUtil.GetEditorConf();
}
private void OnGUI()
{
var labelStyle = new GUIStyle(EditorStyles.boldLabel);
labelStyle.fontSize = 14;
labelStyle.margin.left = 20;
labelStyle.margin.top = 10;
labelStyle.margin.bottom = 10;
GUILayout.Label("基本设置", labelStyle);
var inputStyle = new GUIStyle(EditorStyles.textField);
inputStyle.fontSize = 14;
inputStyle.margin.left = 20;
inputStyle.margin.bottom = 10;
inputStyle.margin.right = 20;
GUIStyle toggleStyle = new GUIStyle(GUI.skin.toggle);
toggleStyle.margin.left = 20;
toggleStyle.margin.right = 20;
miniGameConf.CompressTexture.bundleSuffix = EditorGUILayout.TextField(new GUIContent("bunlde文件后缀(?)", "多个不同后缀可用;分割开来"),miniGameConf.CompressTexture.bundleSuffix, inputStyle);
GUILayout.Label(new GUIContent("功能选项(?)", "每次变更了下列选项都需要重新发布小游戏包"), labelStyle);
GUILayout.BeginHorizontal();
var labelStyle2 = new GUIStyle(EditorStyles.label);
labelStyle2.margin.left = 20;
GUILayout.Label(new GUIContent("支持PC端压缩纹理(?)", "使PC微信也支持压缩纹理不过会在开发阶段增加纹理生成耗时。"), labelStyle2, GUILayout.Height(22), GUILayout.Width(150));
miniGameConf.CompressTexture.useDXT5 = GUILayout.Toggle(miniGameConf.CompressTexture.useDXT5, "", GUILayout.Height(22), GUILayout.Width(50));
GUILayout.Label(new GUIContent("纹理与bundle并行加载(?)", "默认纹理是解析bundle后才加载勾选后加载bundle时bundle对应纹理就会同时加载。"), labelStyle2, GUILayout.Height(22), GUILayout.Width(150));
miniGameConf.CompressTexture.parallelWithBundle = GUILayout.Toggle(miniGameConf.CompressTexture.parallelWithBundle, "", GUILayout.Height(22), GUILayout.Width(50));
GUILayout.EndHorizontal();
GUILayout.Label(new GUIContent("自定义目录(?)", "默认不用选择"), labelStyle);
var labelStyle3 = new GUIStyle(EditorStyles.boldLabel);
labelStyle3.fontSize = 12;
labelStyle3.margin.left = 20;
labelStyle3.margin.top = 10;
labelStyle3.margin.bottom = 10;
GUILayout.Label("bundle路径", labelStyle3);
var chooseBundlePathButtonClicked = false;
var openBundleButtonClicked = false;
var resetBundleButtonClicked = false;
int pathButtonHeight = 28;
GUIStyle pathLabelStyle = new GUIStyle(GUI.skin.textField);
pathLabelStyle.fontSize = 12;
pathLabelStyle.alignment = TextAnchor.MiddleLeft;
pathLabelStyle.margin.top = 6;
pathLabelStyle.margin.bottom = 6;
pathLabelStyle.margin.left = 20;
if (string.IsNullOrEmpty(miniGameConf.CompressTexture.bundleDir))
{
GUIStyle pathButtonStyle2 = new GUIStyle(GUI.skin.button);
pathButtonStyle2.fontSize = 12;
pathButtonStyle2.margin.left = 20;
chooseBundlePathButtonClicked = GUILayout.Button("选择自定义bundle路径默认不用选", pathButtonStyle2, GUILayout.Height(30), GUILayout.Width(300));
}
else
{
GUILayout.BeginHorizontal();
// 路径框
GUILayout.Label(miniGameConf.CompressTexture.bundleDir, pathLabelStyle, GUILayout.Height(pathButtonHeight - 6), GUILayout.ExpandWidth(true), GUILayout.MaxWidth(EditorGUIUtility.currentViewWidth - 126));
openBundleButtonClicked = GUILayout.Button("打开", GUILayout.Height(pathButtonHeight), GUILayout.Width(40));
resetBundleButtonClicked = GUILayout.Button("重选", GUILayout.Height(pathButtonHeight), GUILayout.Width(40));
GUILayout.EndHorizontal();
}
EditorGUILayout.Space();
if (chooseBundlePathButtonClicked)
{
// 弹出选目录窗口
var dstPath = EditorUtility.SaveFolderPanel("选择你的bundle目录", "", "");
if (dstPath != "")
{
miniGameConf.CompressTexture.bundleDir = dstPath;
}
}
if (openBundleButtonClicked)
{
UnityUtil.ShowInExplorer(miniGameConf.CompressTexture.bundleDir);
}
if (resetBundleButtonClicked)
{
miniGameConf.CompressTexture.bundleDir = "";
}
GUILayout.Label("自定义资源处理后存放路径", labelStyle3);
var chooseDstPathButtonClicked = false;
var openDstButtonClicked = false;
var resetDstButtonClicked = false;
if (string.IsNullOrEmpty(miniGameConf.CompressTexture.dstMinDir))
{
GUIStyle pathButtonStyle2 = new GUIStyle(GUI.skin.button);
pathButtonStyle2.fontSize = 12;
pathButtonStyle2.margin.left = 20;
chooseDstPathButtonClicked = GUILayout.Button("选择自定义资源处理后存放路径,默认不用选", pathButtonStyle2, GUILayout.Height(30), GUILayout.Width(300));
}
else
{
GUILayout.BeginHorizontal();
// 路径框
GUILayout.Label(miniGameConf.CompressTexture.dstMinDir, pathLabelStyle, GUILayout.Height(pathButtonHeight - 6), GUILayout.ExpandWidth(true), GUILayout.MaxWidth(EditorGUIUtility.currentViewWidth - 126));
openDstButtonClicked = GUILayout.Button("打开", GUILayout.Height(pathButtonHeight), GUILayout.Width(40));
resetDstButtonClicked = GUILayout.Button("重选", GUILayout.Height(pathButtonHeight), GUILayout.Width(40));
GUILayout.EndHorizontal();
}
EditorGUILayout.Space();
if (chooseDstPathButtonClicked)
{
// 弹出选目录窗口
var dstPath = EditorUtility.SaveFolderPanel("选择你的自定义资源处理后存放路径", "", "");
if (dstPath != "")
{
miniGameConf.CompressTexture.dstMinDir = dstPath;
}
}
if (openDstButtonClicked)
{
UnityUtil.ShowInExplorer(miniGameConf.CompressTexture.dstMinDir);
}
if (resetDstButtonClicked)
{
miniGameConf.CompressTexture.dstMinDir = "";
}
GUILayout.Label("操作", labelStyle);
GUIStyle pathButtonStyle = new GUIStyle(GUI.skin.button);
pathButtonStyle.fontSize = 12;
pathButtonStyle.margin.left = 20;
pathButtonStyle.margin.right = 20;
EditorGUILayout.BeginHorizontal();
var replaceTexture = GUILayout.Button(new GUIContent("处理资源(?)", "处理完成后会在导出目录生成webgl-min目录bundle文件要换成使用webgl-min目录下的bundle文件xx.webgl.data.unityweb.bin.txt文件也要换成使用webgl-min目录下对应的文件注意要将导出目录里面Assets目录下的都上传至CDN对应路径小游戏里才会显示成正常的压缩纹理。注意bundle文件不能开启crc校验否则会展示异常。"), pathButtonStyle, GUILayout.Height(40), GUILayout.Width(140));
var goReadMe = GUILayout.Button(new GUIContent("README"), pathButtonStyle, GUILayout.Height(40), GUILayout.Width(80));
EditorGUILayout.EndHorizontal();
if (replaceTexture)
{
ReplaceBundle();
}
if (goReadMe)
{
Application.OpenURL("https://github.com/wechat-miniprogram/minigame-unity-webgl-transform/blob/main/Design/CompressedTexture.md");
}
}
}
}