【GFFrameWork】UI框架2-UI界面自动生成模板代码工具
前言
我们写UI界面会发现有这么一些重复步骤,创建UI Prefab,然后创建对应界面的View脚本,然后创建跟UI节点组件绑定属性字段还有一些框架层面的接口方法。虽然有时候写这些代码不需要经过大脑,并且键盘敲的啪啪啪爽的飞起,但其实很浪费时间,笔者就想可以写个自动生成UI模板的工具,就减少了这样重复机械式的代码,也节约了大量的时间,我们程序员应该善于创造工具,让自己变"懒"。
效果
操作
-
选择菜单Tools->AutoGenUI
-
选择要生成的Prefab界面
-
点击生成,生成想要的一级、二级UI View代码
界面Prefab要求
既然是自动生成,那UI肯定要符合一定的规范,这里我们将要生成属性字段的节点名后面加上@组件名
生成后的效果
这里生成的是二级界面,所以继承的是SubWindow,如果是一级界面则继承WindowBase,SubWindow也是继承的WindowBase。
代码
AutoGenUI.CS
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class AutoGenUI : EditorWindow
{
[MenuItem("Tools/AutoGenUI")]
static void Audo_Gen_UI()
{
EditorWindow.GetWindow<AutoGenUI>();
}
void OnGUI()
{
GUILayout.Label("选择UI节点,自动生成UI脚本,需要生成的组件节点名后面加@组件名");
if (GUILayout.Button("开始生成父窗口"))
{
if (Selection.activeGameObject)
{
Debug.Log("开始生成");
GenUIUtil.GenWindow(Selection.activeGameObject);
AssetDatabase.Refresh();
Debug.Log("生成结束");
}
}
if (GUILayout.Button("开始生成子窗口"))
{
if(Selection.activeGameObject)
{
Debug.Log("开始生成");
GenUIUtil.GenSubWindow(Selection.activeGameObject);
AssetDatabase.Refresh();
Debug.Log("生成结束");
}
}
if (Selection.activeGameObject != null)
{
GUILayout.Label(Selection.activeGameObject.name);
}
}
void OnSelectionChange()
{
// 当我们选着有改变的时候
this.Repaint();
}
}
GenUIUtil.CS
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
public class GenUIUtil
{
const string filePath = "/Code/[email protected]/DialGame/";
static Dictionary<string, string> componentAbbreviation = new Dictionary<string, string>()
{
{"Text","txt_" },
{"Button","btn_" },
{"Transform","tsf_" },
{"Image","img_" },
{"Label","lbl_" },
{"Input","ipt_" },
{"InputField","ifd_"},
};
public static void GenWindow(GameObject selectGameObject)
{
GenUI(true, selectGameObject);
}
public static void GenSubWindow(GameObject selectGameObject)
{
GenUI(false, selectGameObject);
}
static void GenUI(bool windowOrSubWindow, GameObject selectGameObject)
{
string gameObjectName = selectGameObject.name;
string fileName = string.Format("CUI{0}{1}", gameObjectName, windowOrSubWindow ? "Window" : "Widget");
string fatherClass = windowOrSubWindow ? "WindowBase" : "SubWindow";
StreamWriter sw = new StreamWriter(Application.dataPath + filePath + fileName + ".cs");
sw.WriteLine("using GFFramework.UI;");
sw.WriteLine("using UnityEngine;");
sw.WriteLine("using UnityEngine.UI;");
sw.WriteLine("//Create at:" + System.DateTime.Now.ToString());
sw.WriteLine(string.Format("public class {0} : {1}", fileName, fatherClass));
sw.WriteLine("{");
var childs = deepFindChild(selectGameObject.transform);
foreach (var c in childs)
{
var path = getRelativePath(c);
var nameSplite = c.gameObject.name.Split('@');
string componentName = nameSplite[1];
string nodeName = nameSplite[0];
sw.WriteLine(string.Format("\t[TransformPath(\"{0}\")]", path));
sw.WriteLine(string.Format("\tprivate {0} {1};", c.gameObject.name.Split('@')[1], (componentAbbreviation[componentName] + nodeName).Replace(" ", "")));
sw.WriteLine("\n");
}
//构造函数
sw.WriteLine(string.Format("\tpublic {0}(Transform transform) : base(transform)", fileName));
sw.WriteLine("\t{");
sw.WriteLine("\t}");
sw.WriteLine("\n");
//Init
sw.WriteLine("\tpublic override void Init()");
sw.WriteLine("\t{");
sw.WriteLine("\t\tbase.Init();");
sw.WriteLine("\t}");
sw.WriteLine("\n");
//Close
sw.WriteLine("\tpublic override void Close()");
sw.WriteLine("\t{");
sw.WriteLine("\t\tbase.Close();");
sw.WriteLine("\t}");
sw.WriteLine("\n");
//Open
sw.WriteLine("\tpublic override void Open(WindowData data = null)");
sw.WriteLine("\t{");
sw.WriteLine("\t\tbase.Open();");
sw.WriteLine("\t}");
sw.WriteLine("\n");
//Destroy
sw.WriteLine("\tpublic override void Destroy()");
sw.WriteLine("\t{");
sw.WriteLine("\t\tbase.Destroy();");
sw.WriteLine("\t}");
sw.WriteLine("}");
sw.Flush();
sw.Close();
}
static List<Transform> deepFindChild(Transform root)
{
List<Transform> collects = new List<Transform>();
var childs = root.GetComponentsInChildren<Transform>();
foreach (var child in childs)
{
if (child.name.Contains("@"))
collects.Add(child);
}
return collects;
}
static string getRelativePath(Transform obj)
{
if (obj.parent.parent)
{
return getRelativePath(obj.parent) + "/" + obj.name;
}
return obj.name;
}
}
GFFramework地址
https://github.com/dingxiaowei/GFFrameWork