60.消息处理-自定义协议生成工具-协议消息生成-生成枚举
60.1 知识点
协议消息生成主要做什么?
- 协议生成:主要是使用配置文件中读取出来的信息,动态生成对应语言的代码文件。
- 作用:每次添加消息或者数据结构类时,我们不需要再手写代码了。我们不仅可以生成 C# 脚本文件,还可以根据需求生成别的语言的文件。
制作功能前的准备工作
- 协议生成:不会在发布后使用的功能,主要是在开发时使用。
- 实现方式:在 Unity 中将其作为一个编辑器功能来实现,可以专门新建一个 Editor 文件夹(专门放编辑器相关内容,不会发布),在其中放置配置文件和自动生成相关脚本文件。
把上一节课的 xml 文件改名成 ProtocolInfo.xml 放到 Editor 文件夹下
创建 ProtocolTool 类,放在 Editor 文件夹下,类中定义 xml 配置文件所在的路径,加入特性使编辑器中出现生成脚本的按钮
public class ProtocolTool
{
// 配置文件所在路径
private static string PROTO_INFO_PATH = Application.dataPath + "/Editor/ProtocolTool/ProtocolInfo.xml";
[MenuItem("ProtocolTool/生成C#脚本")]
private static void GenerateCSharp()
{
Debug.Log("生成C#代码");
}
[MenuItem("ProtocolTool/生成C++脚本")]
private static void GenerateC()
{
Debug.Log("生成C++代码");
}
[MenuItem("ProtocolTool/生成Java脚本")]
private static void GenerateJava()
{
Debug.Log("生成Java代码");
}
}
制作生成枚举功能
ProtocolTool 类中定义读取 xml 相关信息的方法
/// <summary>
/// 获取指定名字的所有子节点的 List
/// </summary>
/// <param name="nodeName"></param>
/// <returns></returns>
private static XmlNodeList GetNodes(string nodeName)
{
XmlDocument xml = new XmlDocument();
xml.Load(PROTO_INFO_PATH);
XmlNode root = xml.SelectSingleNode("messages");
return root.SelectNodes(nodeName);
}
定义 GenerateCSharp 类,专门用于生成 C# 代码。定义协议保存路径。之后这个类会写生成枚举,数据结构类,消息类的逻辑。
public class GenerateCSharp
{
// 协议保存路径
private string SAVE_PATH = Application.dataPath + "/Scripts/Protocol/";
// 生成枚举
public void GenerateEnum(XmlNodeList nodes)
{
}
// 生成数据结构类
// 生成消息类
}
在 ProtocolTool 类定义静态 GenerateCSharp 类对象。生成 C# 脚本的方法中调用 GenerateCSharp 类对象生成枚举函数,传入所有的枚举 xml 节点列表。
private static GenerateCSharp generateCSharp = new GenerateCSharp();
[MenuItem("ProtocolTool/生成C#脚本")]
private static void GenerateCSharp()
{
// 读取 xml 相关的信息
// XmlNodeList list = GetNodes("enum");
// 根据这些信息 去拼接字符串 生成对应的脚本
generateCSharp.GenerateEnum(GetNodes("enum"));
// 刷新编辑器界面 让我们可以看到生成的内容 不需要手动进行刷新了
AssetDatabase.Refresh();
}
观察自己声明的枚举类应该怎么拼接,等一下照着拼
namespace GamePlayer
{
public enum E_PLAYER_TYPE
{
// 枚举字段
MAIN = 1,
OTHER,
}
}
根据枚举相关信息实现 GenerateCSharp 类的生成枚举函数,拼接字符串,生成枚举脚本文件
// 生成枚举
public void GenerateEnum(XmlNodeList nodes)
{
// 生成枚举脚本的逻辑
string namespaceStr = "";
string enumNameStr = "";
string fieldStr = "";
foreach (XmlNode enumNode in nodes)
{
// 获取命名空间配置信息
namespaceStr = enumNode.Attributes["namespace"].Value;
// 获取枚举名配置信息
enumNameStr = enumNode.Attributes["name"].Value;
// 获取所有的字段节点 然后进行字符串拼接
XmlNodeList enumFields = enumNode.SelectNodes("field");
// 一个新的枚举 需要清空一次上一次拼接的字段字符串
fieldStr = "";
foreach (XmlNode enumField in enumFields)
{
fieldStr += "\t\t" + enumField.Attributes["name"].Value;
if (enumField.InnerText != "")
fieldStr += " = " + enumField.InnerText;
fieldStr += ",\r\n";
}
// 对所有可变的内容进行拼接
string enumStr = $"namespace {namespaceStr}\r\n" +
"
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com