359 lines
14 KiB
C#
359 lines
14 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using UnityEditor;
|
||
using UnityEngine;
|
||
|
||
namespace WeChatWASM
|
||
{
|
||
[InitializeOnLoad]
|
||
public class WXPlayableSettingsHelperInterface
|
||
{
|
||
public static WXPlayableSettingsHelper helper = new WXPlayableSettingsHelper();
|
||
}
|
||
|
||
public class WXPlayableSettingsHelper
|
||
{
|
||
public static string projectRootPath;
|
||
private static WXPlayableEditorScriptObject config;
|
||
private static bool m_EnablePerfTool = false;
|
||
public static bool UseIL2CPP
|
||
{
|
||
get
|
||
{
|
||
#if TUANJIE_2022_3_OR_NEWER
|
||
return PlayerSettings.GetScriptingBackend(BuildTargetGroup.WeixinMiniGame) == ScriptingImplementation.IL2CPP;
|
||
#else
|
||
return true;
|
||
#endif
|
||
}
|
||
}
|
||
|
||
public WXPlayableSettingsHelper()
|
||
{
|
||
projectRootPath = System.IO.Path.GetFullPath(Application.dataPath + "/../");
|
||
}
|
||
|
||
public void OnFocus()
|
||
{
|
||
loadData();
|
||
}
|
||
|
||
public void OnLostFocus()
|
||
{
|
||
saveData();
|
||
}
|
||
|
||
public void OnDisable()
|
||
{
|
||
EditorUtility.SetDirty(config);
|
||
}
|
||
|
||
private Vector2 scrollRoot;
|
||
private bool foldBaseInfo = true;
|
||
private bool foldDebugOptions = true;
|
||
public void OnSettingsGUI(EditorWindow window)
|
||
{
|
||
scrollRoot = EditorGUILayout.BeginScrollView(scrollRoot);
|
||
GUIStyle linkStyle = new GUIStyle(GUI.skin.label);
|
||
linkStyle.normal.textColor = Color.yellow;
|
||
linkStyle.hover.textColor = Color.yellow;
|
||
linkStyle.stretchWidth = false;
|
||
linkStyle.alignment = TextAnchor.UpperLeft;
|
||
linkStyle.wordWrap = true;
|
||
|
||
foldBaseInfo = EditorGUILayout.Foldout(foldBaseInfo, "基本信息");
|
||
if (foldBaseInfo)
|
||
{
|
||
EditorGUILayout.BeginVertical("frameBox", GUILayout.ExpandWidth(true));
|
||
this.formInput("appid", "小游戏试玩AppID");
|
||
this.formInput("projectName", "小游戏试玩项目名");
|
||
this.formIntPopup("orientation", "游戏方向", new[] { "Portrait", "Landscape" }, new[] { 0, 1, 2, 3 });
|
||
this.formInput("memorySize", "UnityHeap预留内存(?)", "单位MB,预分配内存值,超休闲游戏256/中轻度496/重度游戏768,需预估游戏最大UnityHeap值以防止内存自动扩容带来的峰值尖刺。预估方法请查看GIT文档《优化Unity WebGL的内存》");
|
||
|
||
GUILayout.BeginHorizontal();
|
||
string targetDst = "dst";
|
||
if (!formInputData.ContainsKey(targetDst))
|
||
{
|
||
formInputData[targetDst] = "";
|
||
}
|
||
EditorGUILayout.LabelField(string.Empty, GUILayout.Width(10));
|
||
GUILayout.Label(new GUIContent("导出路径(?)", "支持输入相对于项目根目录的相对路径,如:wxbuild"), GUILayout.Width(140));
|
||
formInputData[targetDst] = GUILayout.TextField(formInputData[targetDst], GUILayout.MaxWidth(EditorGUIUtility.currentViewWidth - 270));
|
||
if (GUILayout.Button(new GUIContent("打开"), GUILayout.Width(40)))
|
||
{
|
||
if (!formInputData[targetDst].Trim().Equals(string.Empty))
|
||
{
|
||
EditorUtility.RevealInFinder(GetAbsolutePath(formInputData[targetDst]));
|
||
}
|
||
GUIUtility.ExitGUI();
|
||
}
|
||
if (GUILayout.Button(new GUIContent("选择"), GUILayout.Width(40)))
|
||
{
|
||
var dstPath = EditorUtility.SaveFolderPanel("选择你的游戏导出目录", string.Empty, string.Empty);
|
||
if (dstPath != string.Empty)
|
||
{
|
||
formInputData[targetDst] = dstPath;
|
||
this.saveData();
|
||
}
|
||
GUIUtility.ExitGUI();
|
||
}
|
||
GUILayout.EndHorizontal();
|
||
|
||
|
||
EditorGUILayout.EndVertical();
|
||
}
|
||
|
||
foldDebugOptions = EditorGUILayout.Foldout(foldDebugOptions, "调试编译选项");
|
||
if (foldDebugOptions)
|
||
{
|
||
EditorGUILayout.BeginVertical("frameBox", GUILayout.ExpandWidth(true));
|
||
this.formCheckbox("developBuild", "Development Build", "", false, null, OnDevelopmentBuildToggleChanged);
|
||
this.formCheckbox("il2CppOptimizeSize", "Il2Cpp Optimize Size(?)", "对应于Il2CppCodeGeneration选项,勾选时使用OptimizeSize(默认推荐),生成代码小15%左右,取消勾选则使用OptimizeSpeed。游戏中大量泛型集合的高频访问建议OptimizeSpeed,在使用HybridCLR等第三方组件时只能用OptimizeSpeed。(Dotnet Runtime模式下该选项无效)", !UseIL2CPP);
|
||
this.formCheckbox("profilingFuncs", "Profiling Funcs");
|
||
this.formCheckbox("webgl2", "WebGL2.0");
|
||
EditorGUILayout.EndVertical();
|
||
}
|
||
|
||
EditorGUILayout.EndScrollView();
|
||
}
|
||
public void OnBuildButtonGUI(EditorWindow window)
|
||
{
|
||
GUIStyle linkStyle = new GUIStyle(GUI.skin.label);
|
||
linkStyle.normal.textColor = Color.yellow;
|
||
linkStyle.hover.textColor = Color.yellow;
|
||
linkStyle.stretchWidth = false;
|
||
linkStyle.alignment = TextAnchor.UpperLeft;
|
||
linkStyle.wordWrap = true;
|
||
EditorGUILayout.BeginHorizontal();
|
||
EditorGUILayout.LabelField(string.Empty, GUILayout.MinWidth(10));
|
||
if (GUILayout.Button(new GUIContent("生成并转换"), GUILayout.Width(100), GUILayout.Height(25)))
|
||
{
|
||
this.saveData();
|
||
if (WXPlayableConvertCore.DoExport() == WXConvertCore.WXExportError.SUCCEED)
|
||
{
|
||
window.ShowNotification(new GUIContent("转换完成"));
|
||
}
|
||
GUIUtility.ExitGUI();
|
||
}
|
||
EditorGUILayout.EndHorizontal();
|
||
}
|
||
private void OnDevelopmentBuildToggleChanged(bool InNewValue)
|
||
{
|
||
// 针对non-dev build,取消性能分析工具的集成
|
||
if (!InNewValue)
|
||
{
|
||
this.setData("enablePerfAnalysis", false);
|
||
}
|
||
}
|
||
|
||
private string SDKFilePath;
|
||
|
||
private void loadData()
|
||
{
|
||
SDKFilePath = Path.Combine(UnityUtil.GetWxSDKRootPath(), "Runtime", "wechat-playable-default", "unity-sdk", "index.js");
|
||
config = UnityUtil.GetPlayableEditorConf();
|
||
|
||
this.setData("projectName", config.ProjectConf.projectName);
|
||
this.setData("appid", config.ProjectConf.Appid);
|
||
this.setData("orientation", (int)config.ProjectConf.Orientation);
|
||
this.setData("dst", config.ProjectConf.relativeDST);
|
||
|
||
this.setData("developBuild", config.CompileOptions.DevelopBuild);
|
||
this.setData("il2CppOptimizeSize", config.CompileOptions.Il2CppOptimizeSize);
|
||
this.setData("profilingFuncs", config.CompileOptions.profilingFuncs);
|
||
this.setData("webgl2", config.CompileOptions.Webgl2);
|
||
this.setData("customNodePath", config.CompileOptions.CustomNodePath);
|
||
|
||
this.setData("memorySize", config.ProjectConf.MemorySize.ToString());
|
||
}
|
||
|
||
private void saveData()
|
||
{
|
||
config.ProjectConf.projectName = this.getDataInput("projectName");
|
||
config.ProjectConf.Appid = this.getDataInput("appid");
|
||
config.ProjectConf.Orientation = (WXScreenOritation)this.getDataPop("orientation");
|
||
config.ProjectConf.relativeDST = this.getDataInput("dst");
|
||
config.ProjectConf.DST = GetAbsolutePath(config.ProjectConf.relativeDST);
|
||
|
||
config.CompileOptions.DevelopBuild = this.getDataCheckbox("developBuild");
|
||
config.CompileOptions.Il2CppOptimizeSize = this.getDataCheckbox("il2CppOptimizeSize");
|
||
config.CompileOptions.profilingFuncs = this.getDataCheckbox("profilingFuncs");
|
||
config.CompileOptions.CustomNodePath = this.getDataInput("customNodePath");
|
||
config.CompileOptions.Webgl2 = this.getDataCheckbox("webgl2");
|
||
config.ProjectConf.MemorySize = int.Parse(this.getDataInput("memorySize"));
|
||
}
|
||
|
||
private Dictionary<string, string> formInputData = new Dictionary<string, string>();
|
||
private Dictionary<string, int> formIntPopupData = new Dictionary<string, int>();
|
||
private Dictionary<string, bool> formCheckboxData = new Dictionary<string, bool>();
|
||
|
||
private string getDataInput(string target)
|
||
{
|
||
if (this.formInputData.ContainsKey(target))
|
||
return this.formInputData[target];
|
||
return "";
|
||
}
|
||
|
||
private int getDataPop(string target)
|
||
{
|
||
if (this.formIntPopupData.ContainsKey(target))
|
||
return this.formIntPopupData[target];
|
||
return 0;
|
||
}
|
||
|
||
private bool getDataCheckbox(string target)
|
||
{
|
||
if (this.formCheckboxData.ContainsKey(target))
|
||
return this.formCheckboxData[target];
|
||
return false;
|
||
}
|
||
|
||
private void formCheckbox(string target, string label, string help = null, bool disable = false, Action<bool> setting = null, Action<bool> onValueChanged = null)
|
||
{
|
||
if (!formCheckboxData.ContainsKey(target))
|
||
{
|
||
formCheckboxData[target] = false;
|
||
}
|
||
GUILayout.BeginHorizontal();
|
||
EditorGUILayout.LabelField(string.Empty, GUILayout.Width(10));
|
||
if (help == null)
|
||
{
|
||
GUILayout.Label(label, GUILayout.Width(140));
|
||
}
|
||
else
|
||
{
|
||
GUILayout.Label(new GUIContent(label, help), GUILayout.Width(140));
|
||
}
|
||
EditorGUI.BeginDisabledGroup(disable);
|
||
|
||
// Toggle the checkbox value based on the disable condition
|
||
bool newValue = EditorGUILayout.Toggle(disable ? false : formCheckboxData[target]);
|
||
// Update the checkbox data if the value has changed and invoke the onValueChanged action
|
||
if (newValue != formCheckboxData[target])
|
||
{
|
||
formCheckboxData[target] = newValue;
|
||
onValueChanged?.Invoke(newValue);
|
||
}
|
||
|
||
if (setting != null)
|
||
{
|
||
EditorGUILayout.LabelField("", GUILayout.Width(10));
|
||
// 配置按钮
|
||
if (GUILayout.Button(new GUIContent("设置"), GUILayout.Width(40), GUILayout.Height(18)))
|
||
{
|
||
setting?.Invoke(true);
|
||
}
|
||
EditorGUILayout.LabelField("", GUILayout.MinWidth(10));
|
||
}
|
||
|
||
EditorGUI.EndDisabledGroup();
|
||
|
||
if (setting == null)
|
||
EditorGUILayout.LabelField(string.Empty);
|
||
GUILayout.EndHorizontal();
|
||
}
|
||
|
||
private void setData(string target, string value)
|
||
{
|
||
if (formInputData.ContainsKey(target))
|
||
{
|
||
formInputData[target] = value;
|
||
}
|
||
else
|
||
{
|
||
formInputData.Add(target, value);
|
||
}
|
||
}
|
||
|
||
private void setData(string target, bool value)
|
||
{
|
||
if (formCheckboxData.ContainsKey(target))
|
||
{
|
||
formCheckboxData[target] = value;
|
||
}
|
||
else
|
||
{
|
||
formCheckboxData.Add(target, value);
|
||
}
|
||
}
|
||
|
||
private void setData(string target, int value)
|
||
{
|
||
if (formIntPopupData.ContainsKey(target))
|
||
{
|
||
formIntPopupData[target] = value;
|
||
}
|
||
else
|
||
{
|
||
formIntPopupData.Add(target, value);
|
||
}
|
||
}
|
||
|
||
private void formInput(string target, string label, string help = null)
|
||
{
|
||
if (!formInputData.ContainsKey(target))
|
||
{
|
||
formInputData[target] = "";
|
||
}
|
||
GUILayout.BeginHorizontal();
|
||
EditorGUILayout.LabelField(string.Empty, GUILayout.Width(10));
|
||
if (help == null)
|
||
{
|
||
GUILayout.Label(label, GUILayout.Width(140));
|
||
}
|
||
else
|
||
{
|
||
GUILayout.Label(new GUIContent(label, help), GUILayout.Width(140));
|
||
}
|
||
formInputData[target] = GUILayout.TextField(formInputData[target], GUILayout.MaxWidth(EditorGUIUtility.currentViewWidth - 195));
|
||
GUILayout.EndHorizontal();
|
||
}
|
||
|
||
private void formIntPopup(string target, string label, string[] options, int[] values)
|
||
{
|
||
if (!formIntPopupData.ContainsKey(target))
|
||
{
|
||
formIntPopupData[target] = 0;
|
||
}
|
||
GUILayout.BeginHorizontal();
|
||
EditorGUILayout.LabelField(string.Empty, GUILayout.Width(10));
|
||
GUILayout.Label(label, GUILayout.Width(140));
|
||
formIntPopupData[target] = EditorGUILayout.IntPopup(formIntPopupData[target], options, values, GUILayout.MaxWidth(EditorGUIUtility.currentViewWidth - 195));
|
||
GUILayout.EndHorizontal();
|
||
}
|
||
|
||
public static bool IsAbsolutePath(string path)
|
||
{
|
||
// 检查是否为空或空白
|
||
if (string.IsNullOrWhiteSpace(path))
|
||
{
|
||
return false;
|
||
}
|
||
|
||
// 在 Windows 上,检查驱动器字母或网络路径
|
||
if (Application.platform == RuntimePlatform.WindowsEditor && Path.IsPathRooted(path))
|
||
{
|
||
return true;
|
||
}
|
||
|
||
// 在 Unix/Linux 和 macOS 上,检查是否以 '/' 开头
|
||
if (Application.platform == RuntimePlatform.OSXEditor && path.StartsWith("/"))
|
||
{
|
||
return true;
|
||
}
|
||
|
||
return false; // 否则为相对路径
|
||
}
|
||
|
||
public static string GetAbsolutePath(string path)
|
||
{
|
||
if (IsAbsolutePath(path))
|
||
{
|
||
return path;
|
||
}
|
||
|
||
return Path.Combine(projectRootPath, path);
|
||
}
|
||
}
|
||
} |