在项目中使用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复制测试: