自动生产代码
一、前言
由于之前写过关于UI框架的文章,这篇基于之前的基础,添加了自动生成代码的功能;
如果学习过程有困惑可以跳转到之前的文章《Unity——基于UGUI的UI框架》;
二、效果展示
三、将UIFrame打包成dll
我使用的是Rider编辑器,用其他的也可以;
目的就是将之前写好的UIFrame框架的几个公共类打包成dll供调用,只有打包成dll才可以在Plugins和Scripts文件夹中都能使用;
操作步骤如下:
1.创建新的classLibrary解决方案:
2.导入写好的类,目前只需要到这以下这三个类即可;
这几个类要添加统一的命名空间,只有在其他项目使用只需要using这个命名空间即可;
3.点击BuildSolution打包;
由于这几个类继承了MonoBehaviour,需要添加UnityEngine依赖,根据错误提示添加;
另外.Net的版本过高也会导致打包出错,修改一下版本即可;
四、自动生成代码
主要方法类UGUITool;由于是编辑器拓展功能,必须放在plugins文件夹下;
字段:
uiDirPath:所有面板加载路径;
classPath:自动生成的代码存放路径;
classTemp:自动化代码模板字符串;
方法:
CreateCode():核心方法;
思路:
1.根据面板加载路径,读取所有面板的prefab信息;
2.根据预制体的名称,自动生成@Init和@UIType部分的代码字符串;
3.字符串全部生成完成后替换对应部分,保存在存放路径;
注意:
我这里所有面板都是放在Resources中的,如果正式项目肯定不会Resources加载,所以需要做SteamingAssets路径判断;
代码部分:
public class UGUITool
{
public static string uiDirPath = "Resources/Prefabs/UIPanel/";
public static string classPath = "Scripts/UIFrame/UIManagerA.cs";
private static string classTemp =
@"
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UIFrame;
public partial class UIManager : MonoSingle<UIManager>
{
private void InitPath()
{
dicPath = new Dictionary<string, string>();
//@Init
}
}
public class UIType
{
//@UIType
}
";
[MenuItem("LittlePerilla/UGUI/CreateCode")]
public static void CreateCode()
{
//Resources可以替换
string path = Path.Combine(Application.dataPath, uiDirPath);
Debug.Log("生成代码" + path);
StringBuilder pt = new StringBuilder();
StringBuilder tp = new StringBuilder();
GameObject go = null;
string[] fileList = Directory.GetFiles(path, "*.prefab", SearchOption.AllDirectories);
int index = 0;
string s = "Resources";
foreach (var filePath in fileList)
{
string newPath = string.Empty;
newPath = filePath.Replace("\\", "/");
if (newPath.Contains(s))
{
newPath = newPath.Substring(newPath.IndexOf(s) + s.Length + 1);
newPath = newPath.Substring(0, newPath.IndexOf("."));
go = Resources.Load<GameObject>(newPath);
}
else
{
//newPath = newPath.Substring(0, newPath.IndexOf(".")); //其他路径必须加后缀名
go = AssetDatabase.LoadAssetAtPath<GameObject>(newPath) as GameObject;
}
if (go == null)
{
Debug.LogError(newPath);
continue;
}
if (go.GetComponent<UIBase>())
{
string name = go.name.ToLower();
string uiName = $"UI{name.Substring(3, 1).ToUpper()}{name.Substring(4, name.Length-4)}";
pt.AppendLine($"dicPath[\"{name}\"] = \"{newPath}\";");
tp.AppendLine($"public const string {uiName} = \"{name}\";");
index++;
}
}
string codeClass = classTemp.Replace("//@Init", pt.ToString());
codeClass = codeClass.Replace("//@UIType", tp.ToString());
path = Path.Combine(Application.dataPath, classPath);
File.WriteAllText(path, codeClass, Encoding.UTF8);
Debug.Log($"{codeClass}生成完毕");
AssetDatabase.Refresh();
}
}
五、使用须知
路径必须设置正常,并且之后所有UI面板都必须放在对应的文件夹下才会自动生成对应的代码;
自动化代码是提高工作效率的重要手段,如果有修改意见请与作者联系;