【此篇针对于UNITY】
最近在自己搭破架子 碰到一个问题:
我的Panel类是要在运行时 全部预先创建实例 这就有个很闹心的问题 我加一个新的 就要去预读取类中加上这个类的代码
emmmmm 很闹心 所以就做了工作来生成代码

开始吧~

简单一点 先创建三个类【本来是应该继承自基类的 为了方便 就不继承了】

public class Panel1 : MonoBehaviour {

    public Panel1()
    {
        Debug.LogFormat("当前文件 Panel1");
    }
}
public class Panel2 : MonoBehaviour {

    public Panel2()
    {
        Debug.LogFormat("当前文件 Panel2");
    }
}
public class Panel3 : MonoBehaviour {

    public Panel3()
    {
        Debug.LogFormat("当前文件 Panel3");
    }
}

然后再来一个预读的类

public class PanelManager {

	public PanelManager()
    {
		Panel1 panel1 = new Panel1();
		Panel2 panel2 = new Panel2();
		Panel3 panel3 = new Panel3();
    }
}

看到了吧 每次有新的类 都要手动加进来

所以在工具栏中 加一个按钮吧

unity 执行sh文件_文件名


先看一下目录结构

unity 执行sh文件_List_02


PanelManager是运行时预读的类

Panel1 Panel2 Panel3是要预读的类

GenerateFileMenu是工具栏扩展的类

首先来改造一下PanelManager 添加一个标识符 用来标识要修改的地方

public class PanelManager {

	public PanelManager()
    {
        //#@#@# 生成开始标识符
		Panel1 panel1 = new Panel1();
		Panel2 panel2 = new Panel2();
		Panel3 panel3 = new Panel3();
        //@#@#@ 生成结束标识符
    }
}

接下来看一下这个工具栏扩展类做了啥

//生成菜单
public class GenerateFileMenu {

    [MenuItem("文件生成/生成Panel预读取数据 %#_g", false, 100)]
    private static void GeneratePrePanelLoadData()
    {
        Debug.Log("生成数据");
        //加载程序集 ①
        Assembly assem = Assembly.Load("Assembly-CSharp");
        //存储读出的内容
        List<string> fileStrList = new List<string>();
        //读取预加载管理文件  ②
        string filePath = @"Assets/Script/PanelManager.cs";
        StreamReader readFileStream = new StreamReader(filePath);
        while (!readFileStream.EndOfStream)
        {
            string fileLine = readFileStream.ReadLine();
            fileStrList.Add(fileLine);
        }
        //③
        readFileStream.Close();

        //重新写入文件 ④
        StreamWriter writeFileStream = new StreamWriter(filePath, false, Encoding.UTF8);
        bool isInserting = false;
        foreach (string fileStr in fileStrList)
        {
            if (true == isInserting)
            {
                //是否开始插入 ⑤
                if (true == fileStr.Contains("@#@#@"))
                {
                    writeFileStream.WriteLine(fileStr);
                    isInserting = false;
                }
            }
            else
            {
                writeFileStream.WriteLine(fileStr);
                //是否开始插入
                if (true == fileStr.Contains("#@#@#"))
                {
                    isInserting = true;
                    //获取全部Panel文件名 ⑥
                    string panelPath = "Assets/Script/PanelScript";
                    List<string> nameStrList = GetFilesInEachLayerDirectory(panelPath, "*.cs");
                    foreach (string nameAllStr in nameStrList)
                    {
                    	//⑦
                        string nameStr = nameAllStr.Split('.')[0];
                        //⑧
                        Type clsType = assem.GetType(nameStr);
                        if (null == clsType)
                        {
                            Debug.LogFormat("程序集中找不到{0}这个类", nameStr);
                        }
                        else
                        {
                        	//⑨
                            string fUpperValue = nameStr.Substring(0, 1).ToUpper() + nameStr.Substring(1);
                            string fLowerValue = nameStr.Substring(0, 1).ToLower() + nameStr.Substring(1);
                            writeFileStream.WriteLine(string.Format("\t\t{0} {1} = new {2}();", fUpperValue, fLowerValue, fUpperValue));
                        }
                    }
                }

            }
        }
        writeFileStream.Close();
    }

    //获取目录和子目录下所有文件
    private static List<string> GetFilesInEachLayerDirectory(string path, string extension = "*")
    {
        //文件名列表
        List<string> nameStrList = new List<string>();
        //获取目录下数据
        DirectoryInfo root = new DirectoryInfo(path);
        //读取所有文件
        foreach (FileInfo file in root.GetFiles(extension))
        {
            nameStrList.Add(file.Name);
        }
        //子目录查找
        foreach (DirectoryInfo folder in root.GetDirectories())
        {
            string folderPath = path + "/" + folder.Name;
            List<string> deepNameStrList = GetFilesInEachLayerDirectory(folderPath, extension);
            foreach (string nameStr in deepNameStrList)
            {
                nameStrList.Add(nameStr);
            }
        }
        return nameStrList;
    }
}

①因为Editor和功能不是一个DLL 所以这里要先加载程序集 可以在你的项目中看一下叫什么

unity 执行sh文件_文件名_03


②这里的路径用了@ 是为了让字符串不做转译

可以看这里

③记得读取完数据 要关上啊 不然后面写入的时候 就会报错的

④重新写入文件 用UTF-8 防止乱码

⑤这里用了Contains来匹配刚刚加进去的标识符

⑥GetFilesInEachLayerDirectory这个方法就是遍历目录下所有的cs文件

⑦这里获取到的是完整的文件名 所以分割一下 把文件后缀名去掉

⑧这里通过程序集来反射出类 【这里我试了很久 原来是要用加载的程序集才行 现在我终于懂了反射是怎么回事了】

这里倒是有个问题 文件名和类名要相同 所以我就给自己定个潜规则 文件名和类名要相同 【我暂时没有别的办法】

⑨这里就开始写入代码了 根据需要来写就好了

差不多就是这样 Ctrl+Shift+G 直接就生成好了 稳得一批