61.自定义协议工具生成数据结构类成员变量

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

×

喜欢就点赞,疼爱就打赏