Unity 编辑器开发实战【Editor Window】- 关于提高Proto通信协议文件生成效率的考虑

2022-08-29 17:00:43 浏览数 (1)

在项目中使用Protobuf作为通信协议时,需要用到protogen.exe程序将.proto文件编译成.cs文件再导入Unity工程中使用:

例如我们创建一个ProtoTest.proto文件:

然后编辑run.bat文件中的内容,根据.proto文件名称输入编译指令:

编辑完成后,运行run.bat文件,可见编译好的ProtoTest.cs文件已经生成到指定位置:

当我们有大量的.proto文件需要编译时,手动输入这些编译指令费时费力,而且容易出错,基于这样的情况,博主在Unity中编写了一个便利的工具:

只需要指定protogen.exe所在的文件夹路径,点击Create .bat按钮,工具会根据proto文件夹内所有.proto文件的名称拼接编译指令,写入run.bat文件,代码如下:

代码语言:javascript复制
using System.IO;
using UnityEngine;
using UnityEditor;
using System.Text;
using System.Diagnostics;

namespace SK.Framework
{
    /// <summary>
    /// Proto通信协议类编译工具
    /// </summary>
    public class Protogen : EditorWindow
    {
        [MenuItem("SKFramework/Protogen")]
        private static void Open()
        {
            GetWindow<Protogen>("Protogen").Show();
        }

        //根路径
        private string rootPath;

        private void OnGUI()
        {
            GUILayout.Label("protogen.exe所在路径:");
            GUILayout.BeginHorizontal();
            {
                rootPath = GUILayout.TextField(rootPath);
                if (GUILayout.Button("Browse", GUILayout.Width(50f)))
                {
                    rootPath = EditorUtility.OpenFolderPanel("选择路径", rootPath, null);
                }
            }
            GUILayout.EndHorizontal();

            GUILayout.FlexibleSpace();
            if (GUILayout.Button("Create .bat", GUILayout.Height(30f)))
            {
                string protoPath = rootPath   "/proto";
                if (!Directory.Exists(protoPath))
                {
                    UnityEngine.Debug.Log($"<color=red>文件夹不存在</color> {protoPath}");
                    return;
                }
                string csPath = rootPath   "/cs";
                //如果cs文件夹不存在则创建
                if (!Directory.Exists(csPath))
                {
                    Directory.CreateDirectory(csPath);
                }
                DirectoryInfo di = new DirectoryInfo(protoPath);
                //获取所有.proto文件信息
                FileInfo[] protos = di.GetFiles("*.proto");
                //使用StringBuilder拼接字符串
                StringBuilder sb = new StringBuilder();
                //遍历
                for (int i = 0; i < protos.Length; i  )
                {
                    string proto = protos[i].Name;
                    //拼接编译指令
                    sb.Append(rootPath   @"/protogen.exe -i:proto"   proto   @" -o:cs"   proto.Replace(".proto", ".cs")   "rn");
                }
                sb.Append("pause");

                //生成".bat文件"
                string batPath = $"{rootPath}/run.bat";
                File.WriteAllText(batPath, sb.ToString());
                //打开该文件夹
                Process.Start(rootPath);
            }
        }
    }
}
代码语言:javascript复制
测试:

0 人点赞