游戏开发中有很多要重复写的代码,尤其是UI面板。所以我们可以写一个编辑器扩展自动生成脚本提高开发效率。逻辑不难代码也不算长,根据注释捋一下逻辑就可以轻松使用啦。
使用方法: 选中Project面板下的UI预制体即可。要注意只会获取dicUIType
字典中符合命名规则目标的路径。
UIClass
是我们创建类的模板,可以根据我们的需求灵活修改。 注意要放在Editor文件夹下。
参考地址
代码部分:
using UnityEngine;
using UnityEditor;
using System.Linq;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using System.Text;
public class AutoBuildTemplate
{
public static string UIClass =
@"using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System;
public class #类名# : MonoBehaviour
{
//auto
#成员#
public void Start()
{
#查找#
}
}
";
}
public class AutoBuild
{
[MenuItem("生成/创建或刷新界面")]
public static void BuildUIScript()
{
var dicUIType = new Dictionary();
dicUIType.Add("Img", "Image");
dicUIType.Add("Btn", "Button");
dicUIType.Add("Txt", "Text");
dicUIType.Add("Tran", "Transform");
//获取选中的prefab
GameObject[] selectobjs = Selection.gameObjects;
foreach (GameObject go in selectobjs)
{
//选择的物体
GameObject selectobj = go.transform.root.gameObject;
//物体的子物体
Transform[] _transforms = selectobj.GetComponentsInChildren(true);
//转换为list
List childList = new List(_transforms);
//UI需要查询的物体,根据规则筛选
var mainNode = from trans in childList where dicUIType.Keys.ToList().Any(_ => trans.name.Contains(_)) select trans;
//存储每个目标路径
var nodePathList = new Dictionary();
//循环得到物体路径
foreach (Transform node in mainNode)
{
Transform tempNode = node;
string nodePath = "/" + tempNode.name;
//遍历到顶,求得路径
while (tempNode != tempNode.root)
{
//取得上级
tempNode = tempNode.parent;
//求出/在哪
int index = nodePath.IndexOf('/');
//把得到的路径插入
nodePath = nodePath.Insert(index, "/" + tempNode.name);
}
//将最终路径存入
nodePathList.Add(node.name, nodePath);
}
//成员变量字符串
string memberstring = "";
//查询代码字符串
string loadedcontant = "";
foreach (Transform itemtran in mainNode)
{
//识别变量类型
string typeStr = dicUIType[dicUIType.Keys.First(_ => itemtran.name.Contains(_))];
//变量声明
memberstring += "private " + typeStr + " " + itemtran.name + " = null;\r\n\t";
//查找语句
loadedcontant += itemtran.name + " = " + "gameObject.transform.Find(\"" + nodePathList[itemtran.name] + "\").GetComponent();\r\n\t\t";
}
//创建脚本的路径
string scriptPath = Application.dataPath + "/Scripts/" + selectobj.name + ".cs";
string classStr = "";
//如果已经存在了脚本,则只替换//auto下方的字符串
//方便刷新
if (File.Exists(scriptPath))
{
FileStream classfile = new FileStream(scriptPath, FileMode.Open);
StreamReader read = new StreamReader(classfile);
classStr = read.ReadToEnd();
read.Close();
classfile.Close();
File.Delete(scriptPath);
//分割的位置
string splitStr = "//auto";
//auto 上面的部分
string unchangeStr = Regex.Split(classStr, splitStr, RegexOptions.IgnoreCase)[0];
//auto 下面的部分
string changeStr = Regex.Split(AutoBuildTemplate.UIClass, splitStr, RegexOptions.IgnoreCase)[1];
StringBuilder build = new StringBuilder();
build.Append(unchangeStr);
build.Append(splitStr);
build.Append(changeStr);
classStr = build.ToString();
}
else
{
classStr = AutoBuildTemplate.UIClass;
}
classStr = classStr.Replace("#类名#", selectobj.name);
classStr = classStr.Replace("#查找#", loadedcontant);
classStr = classStr.Replace("#成员#", memberstring);
FileStream file = new FileStream(scriptPath, FileMode.CreateNew);
StreamWriter fileW = new StreamWriter(file, System.Text.Encoding.UTF8);
fileW.Write(classStr);
fileW.Flush();
fileW.Close();
file.Close();
Debug.Log("创建脚本 " + Application.dataPath + "/Scripts/" + selectobj.name + ".cs 成功!");
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
}
}