61.消息处理-自定义协议生成工具-协议消息生成-生成数据结构类-成员变量
61.1 知识点
分析数据结构类的构成
//1命名空间和需要引用的命名空间
using System.Collections.Generic;
namespace GamePlayer
{
//2类名和继承
public class PlayerData : BaseData
{
//3成员变量
public int id;
public float atk;
public bool sex;
public long lev;
public int[] arrays;
public List<int> list;
public Dictionary<int, string> dic;
public E_HERO_TYPE heroType;
//4成员方法
public override int GetBytesNum()
{
}
public override byte[] Writing()
{
}
public override int Reading(byte[] bytes, int beginIndex = 0)
{
}
}
}
制作生成数据结构类步骤
- 命名空间和需要引用的命名空间
- 类名和继承
- 成员变量声明
- 生成GetBytesNum获取字节数函数
- 生成Writing序列化函数
- 生成Reading反序列化函数
制作生成成员变量声明的功能
观察xml配置中的数据配置
<!--数据结构类配置规则 包含 类名 命名空间 变量类型 变量名-->
<data name="PlayerData" namespace="GamePlayer">
<field type="int" name="id"/>
<field type="float" name="atk"/>
<field type="bool" name="sex"/>
<field type="long" name="lev"/>
<field type="array" data="int" name="arrays"/>
<field type="list" T="int" name="list"/>
<field type="dic" Tkey="int" Tvalue="string" name="dic"/>
<field type="enum" data="E_HERO_TYPE" name="heroType"/>
</data>
<data name="HeartData" namespace="GameSystem">
<field type="long" name="time"/>
</data>
在GenerateCSharp类定义生成成员变量的方法
/// <summary>
/// 获取成员变量声明内容
/// </summary>
/// <param name="fields"></param>
/// <returns></returns>
private string GetFieldStr(XmlNodeList fields)
{
string fieldStr = "";
foreach (XmlNode field in fields)
{
//变量类型
string type = field.Attributes["type"].Value;
//变量名
string fieldName = field.Attributes["name"].Value;
if(type == "list")
{
string T = field.Attributes["T"].Value;
fieldStr += "\t\tpublic List<" + T + "> ";
}
else if(type == "array")
{
string data = field.Attributes["data"].Value;
fieldStr += "\t\tpublic " + data + "[] ";
}
else if(type == "dic")
{
string Tkey = field.Attributes["Tkey"].Value;
string Tvalue = field.Attributes["Tvalue"].Value;
fieldStr += "\t\tpublic Dictionary<" + Tkey + ", " + Tvalue + "> ";
}
else if(type == "enum")
{
string data = field.Attributes["data"].Value;
fieldStr += "\t\tpublic " + data + " ";
}
else
{
fieldStr += "\t\tpublic " + type + " ";
}
fieldStr += fieldName + ";\r\n";
}
return fieldStr;
}
GenerateCSharp类定义生成数据结构类的方法
//生成数据结构类
public void GenerateData(XmlNodeList nodes)
{
string namespaceStr = "";
string classNameStr = "";
string fieldStr = "";
foreach (XmlNode dataNode in nodes)
{
//命名空间
namespaceStr = dataNode.Attributes["namespace"].Value;
//类名
classNameStr = dataNode.Attributes["name"].Value;
//读取所有字段节点
XmlNodeList fields = dataNode.SelectNodes("field");
//通过这个方法进行成员变量声明的拼接 返回拼接结果
fieldStr = GetFieldStr(fields);
string dataStr = "using System.Collections.Generic;\r\n" +
$"namespace {namespaceStr}\r\n" +
"{\r\n" +
$"\tpublic class {classNameStr} : BaseData\r\n" +
"\t{\r\n" +
$"{fieldStr}" +
"\t}\r\n" +
"}";
//保存为 脚本文件
//保存文件的路径
string path = SAVE_PATH + namespaceStr + "/Data/";
//如果不存在这个文件夹 则创建
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
//字符串保存 存储为枚举脚本文件
File.WriteAllText(path + classNameStr + ".cs", dataStr);
}
Debug.Log("数据结构类生成结束");
}
ProtocolTool类中调用生成数据结构类的方法
[MenuItem("ProtocolTool/生成C#脚本")]
private static void GenerateCSharp()
{
//1.读取xml相关的信息
//XmlNodeList list = GetNodes("enum");
//2.根据这些信息 去拼接字符串 生成对应的脚本
//生成对应的枚举脚本
generateCSharp.GenerateEnum(GetNodes("enum"));
//生成对应的数据结构类脚本
generateCSharp.GenerateData(GetNodes("data"));
//刷新编辑器界面 让我们可以看到生成的内容 不需要手动进行刷新了
AssetDatabase.Refresh();
}
点击编辑器按钮查看拼接的成员变量结果
public class PlayerData : BaseData
{
public int id;
public float atk;
public bool sex;
public long lev;
public int[] arrays;
public List<int> list;
public Dictionary<int, string> dic;
public E_HERO_TYPE heroType;
}
public class HeartData : BaseData
{
public long time;
}
61.2 知识点代码
Lesson61_消息处理_自定义协议生成工具_协议消息生成_生成数据结构类_成员变量
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lesson61_消息处理_自定义协议生成工具_协议消息生成_生成数据结构类_成员变量 : MonoBehaviour
{
void Start()
{
#region 知识点一 分析数据结构类的构成
#endregion
#region 知识点二 制作生成数据结构类步骤
//1.命名空间和需要引用的命名空间
//2.类名和继承
//3.成员变量声明
//4.生成GetBytesNum获取字节数函数
//5.生成Writing序列化函数
//6.生成Reading反序列化函数
#endregion
#region 知识点三 制作生成成员变量声明的功能
#endregion
}
}
GenerateCSharp
using System.Collections;
using System.IO;
using System.Xml;
using UnityEngine;
using System.Collections.Generic;
namespace GamePlayer
{
public class PlayerData : BaseData
{
//3成员变量
public int id;
public float atk;
public bool sex;
public long lev;
public int[] arrays;
public List<int> list;
public Dictionary<int, string> dic;
public E_HERO_TYPE heroType;
//4成员方法
public override int GetBytesNum()
{
}
public override byte[] Writing()
{
}
public override int Reading(byte[] bytes, int beginIndex = 0)
{
}
}
}
ProtocolTool
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using UnityEditor;
using UnityEngine;
public class ProtocolTool
{
//配置文件所在路径
private static string PROTO_INFO_PATH = Application.dataPath + "/Editor/ProtocolTool/ProtocolInfo.xml";
private static GenerateCSharp generateCSharp = new GenerateCSharp();
[MenuItem("ProtocolTool/生成C#脚本")]
private static void GenerateCSharp()
{
//1.读取xml相关的信息
//XmlNodeList list = GetNodes("enum");
//2.根据这些信息 去拼接字符串 生成对应的脚本
//生成对应的枚举脚本
generateCSharp.GenerateEnum(GetNodes("enum"));
//生成对应的数据结构类脚本
generateCSharp.GenerateData(GetNodes("data"));
//刷新编辑器界面 让我们可以看到生成的内容 不需要手动进行刷新了
AssetDatabase.Refresh();
}
[MenuItem("ProtocolTool/生成C++脚本")]
private static void GenerateC()
{
Debug.Log("生成C++代码");
}
[MenuItem("ProtocolTool/生成Java脚本")]
private static void GenerateJava()
{
Debug.Log("生成Java代码");
}
/// <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);
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com