Unity—自动化代码生成

自动化代码生成


一.前言

由于之前写过关于UI框架的文章,这篇基于之前的基础,添加了自动生成代码的功能;

如果学习过程有困惑可以跳转到之前的文章《Unity——基于UGUI的UI框架》;

二.效果展示

三.打包UIFrame

我使用的是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面板都必须放在对应的文件夹下才会自动生成对应的代码;

自动化代码是提高工作效率的重要手段,如果有修改意见请与作者联系;

posted @ 2021-10-25 19:36  小紫苏  阅读(1047)  评论(0编辑  收藏  举报