2025-04-22 17:16:40 +08:00

313 lines
12 KiB
C#
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 System.Collections.Generic;
using System.Text;
using UnityEditor;
using UnityEngine;
namespace TEngine.Editor.UI
{
public class ScriptGenerator
{
private const string Gap = "/";
[MenuItem("GameObject/ScriptGenerator/UIProperty", priority = 41)]
public static void MemberProperty()
{
Generate(false);
}
[MenuItem("GameObject/ScriptGenerator/UIProperty - UniTask", priority = 43)]
public static void MemberPropertyUniTask()
{
Generate(false, true);
}
[MenuItem("GameObject/ScriptGenerator/UIPropertyAndListener", priority = 42)]
public static void MemberPropertyAndListener()
{
Generate(true);
}
[MenuItem("GameObject/ScriptGenerator/UIPropertyAndListener - UniTask", priority = 44)]
public static void MemberPropertyAndListenerUniTask()
{
Generate(true, true);
}
private static void Generate(bool includeListener, bool isUniTask = false)
{
var root = Selection.activeTransform;
if (root != null)
{
StringBuilder strVar = new StringBuilder();
StringBuilder strBind = new StringBuilder();
StringBuilder strOnCreate = new StringBuilder();
StringBuilder strCallback = new StringBuilder();
Ergodic(root, root, ref strVar, ref strBind, ref strOnCreate, ref strCallback, isUniTask);
StringBuilder strFile = new StringBuilder();
if (includeListener)
{
#if ENABLE_TEXTMESHPRO
strFile.Append("using TMPro;\n");
#endif
if (isUniTask)
{
strFile.Append("using Cysharp.Threading.Tasks;\n");
}
strFile.Append("using UnityEngine;\n");
strFile.Append("using UnityEngine.UI;\n");
strFile.Append("using TEngine;\n\n");
strFile.Append($"namespace {ScriptGeneratorSetting.GetUINameSpace()}\n");
strFile.Append("{\n");
var widgetPrefix = $"{(ScriptGeneratorSetting.GetCodeStyle() == UIFieldCodeStyle.MPrefix ? "m_" : "_")}{ScriptGeneratorSetting.GetWidgetName()}";
if (root.name.StartsWith(widgetPrefix))
{
strFile.Append("\tclass " + root.name.Replace(widgetPrefix, "") + " : UIWidget\n");
}
else
{
strFile.Append("\t[Window(UILayer.UI)]\n");
strFile.Append("\tclass " + root.name + " : UIWindow\n");
}
strFile.Append("\t{\n");
}
// 脚本工具生成的代码
strFile.Append("\t\t#region 脚本工具生成的代码\n");
strFile.Append(strVar);
strFile.Append("\t\tprotected override void ScriptGenerator()\n");
strFile.Append("\t\t{\n");
strFile.Append(strBind);
strFile.Append(strOnCreate);
strFile.Append("\t\t}\n");
strFile.Append("\t\t#endregion");
if (includeListener)
{
strFile.Append("\n\n");
// #region 事件
strFile.Append("\t\t#region 事件\n");
strFile.Append(strCallback);
strFile.Append("\t\t#endregion\n\n");
strFile.Append("\t}\n");
strFile.Append("}\n");
}
TextEditor te = new TextEditor();
te.text = strFile.ToString();
te.SelectAll();
te.Copy();
}
Debug.Log($"脚本已生成到剪贴板请自行Ctl+V粘贴");
}
public static void Ergodic(Transform root, Transform transform, ref StringBuilder strVar, ref StringBuilder strBind, ref StringBuilder strOnCreate,
ref StringBuilder strCallback, bool isUniTask)
{
for (int i = 0; i < transform.childCount; ++i)
{
Transform child = transform.GetChild(i);
WriteScript(root, child, ref strVar, ref strBind, ref strOnCreate, ref strCallback, isUniTask);
if (child.name.StartsWith("m_item"))
{
continue;
}
Ergodic(root, child, ref strVar, ref strBind, ref strOnCreate, ref strCallback, isUniTask);
}
}
private static string GetRelativePath(Transform child, Transform root)
{
StringBuilder path = new StringBuilder();
path.Append(child.name);
while (child.parent != null && child.parent != root)
{
child = child.parent;
path.Insert(0, Gap);
path.Insert(0, child.name);
}
return path.ToString();
}
public static string GetBtnFuncName(string varName)
{
var codeStyle = ScriptGeneratorSetting.Instance.CodeStyle;
if (codeStyle == UIFieldCodeStyle.MPrefix)
{
return "OnClick" + varName.Replace("m_btn", string.Empty) + "Btn";
}
else
{
return "OnClick" + varName.Replace("_btn", string.Empty) + "Btn";
}
}
public static string GetToggleFuncName(string varName)
{
var codeStyle = ScriptGeneratorSetting.Instance.CodeStyle;
if (codeStyle == UIFieldCodeStyle.MPrefix)
{
return "OnToggle" + varName.Replace("m_toggle", string.Empty) + "Change";
}
else
{
return "OnToggle" + varName.Replace("_toggle", string.Empty) + "Change";
}
}
public static string GetSliderFuncName(string varName)
{
var codeStyle = ScriptGeneratorSetting.Instance.CodeStyle;
if (codeStyle == UIFieldCodeStyle.MPrefix)
{
return "OnSlider" + varName.Replace("m_slider", string.Empty) + "Change";
}
else
{
return "OnSlider" + varName.Replace("_slider", string.Empty) + "Change";
}
}
private static void WriteScript(Transform root, Transform child, ref StringBuilder strVar, ref StringBuilder strBind, ref StringBuilder strOnCreate,
ref StringBuilder strCallback, bool isUniTask)
{
string varName = child.name;
string componentName = string.Empty;
var rule = ScriptGeneratorSetting.GetScriptGenerateRule().Find(t => varName.StartsWith(t.uiElementRegex));
if (rule != null)
{
componentName = rule.componentName;
}
bool isUIWidget = rule is { isUIWidget: true };
if (componentName == string.Empty)
{
return;
}
var codeStyle = ScriptGeneratorSetting.Instance.CodeStyle;
if (codeStyle == UIFieldCodeStyle.UnderscorePrefix)
{
if (varName.StartsWith("_"))
{
}
else if(varName.StartsWith("m_"))
{
varName = varName.Substring(1);
}
else
{
varName = $"_{varName}";
}
}
else if (codeStyle == UIFieldCodeStyle.MPrefix)
{
if (varName.StartsWith("m_"))
{
}
else if (varName.StartsWith("_"))
{
varName = $"m{varName}";
}
else
{
varName = $"m_{varName}";
}
}
string varPath = GetRelativePath(child, root);
if (!string.IsNullOrEmpty(varName))
{
strVar.Append("\t\tprivate " + componentName + " " + varName + ";\n");
switch (componentName)
{
case "Transform":
strBind.Append($"\t\t\t{varName} = FindChild(\"{varPath}\");\n");
break;
case "GameObject":
strBind.Append($"\t\t\t{varName} = FindChild(\"{varPath}\").gameObject;\n");
break;
case "AnimationCurve":
strBind.Append($"\t\t\t{varName} = FindChildComponent<AnimCurveObject>(\"{varPath}\").m_animCurve;\n");
break;
default:
if (isUIWidget)
{
strBind.Append($"\t\t\t{varName} = CreateWidgetByType<{componentName}>(\"{varPath}\");\n");
}
strBind.Append($"\t\t\t{varName} = FindChildComponent<{componentName}>(\"{varPath}\");\n");
break;
}
if (componentName == "Button")
{
string varFuncName = GetBtnFuncName(varName);
if (isUniTask)
{
strOnCreate.Append($"\t\t\t{varName}.onClick.AddListener(UniTask.UnityAction({varFuncName}));\n");
strCallback.Append($"\t\tprivate async UniTaskVoid {varFuncName}()\n");
strCallback.Append("\t\t{\n await UniTask.Yield();\n\t\t}\n");
}
else
{
strOnCreate.Append($"\t\t\t{varName}.onClick.AddListener({varFuncName});\n");
strCallback.Append($"\t\tprivate void {varFuncName}()\n");
strCallback.Append("\t\t{\n\t\t}\n");
}
}
else if (componentName == "Toggle")
{
string varFuncName = GetToggleFuncName(varName);
strOnCreate.Append($"\t\t\t{varName}.onValueChanged.AddListener({varFuncName});\n");
strCallback.Append($"\t\tprivate void {varFuncName}(bool isOn)\n");
strCallback.Append("\t\t{\n\t\t}\n");
}
else if (componentName == "Slider")
{
string varFuncName = GetSliderFuncName(varName);
strOnCreate.Append($"\t\t\t{varName}.onValueChanged.AddListener({varFuncName});\n");
strCallback.Append($"\t\tprivate void {varFuncName}(float value)\n");
strCallback.Append("\t\t{\n\t\t}\n");
}
}
}
public class GeneratorHelper : EditorWindow
{
[MenuItem("GameObject/ScriptGenerator/About", priority = 49)]
public static void About()
{
GeneratorHelper welcomeWindow = (GeneratorHelper)EditorWindow.GetWindow(typeof(GeneratorHelper), false, "About");
}
public void Awake()
{
minSize = new Vector2(400, 600);
}
protected void OnGUI()
{
GUILayout.BeginVertical();
foreach (var item in ScriptGeneratorSetting.GetScriptGenerateRule())
{
GUILayout.Label(item.uiElementRegex + "\t" + item.componentName);
}
GUILayout.EndVertical();
}
}
}
}