IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Unity导表工具制作,可用于ILRuntime下热更使用 -> 正文阅读

[游戏开发]Unity导表工具制作,可用于ILRuntime下热更使用

首先我们明确一下导表工具的目的就是将,策划的表格数据转换为游戏里面程序方便调用的数据格式,一般都是游戏初始换的时候,以字典的结构<Type,<Id,object>> 类似的结构加载表格数据,我们的导表工具就是将Excel表,生成对应的类结构,二进制数据。

1.第一步过滤表格,因为我们的表格是服务器和客户端都放在一起,只是以表头做标志进行区分,如果放在不同的文件夹下的话,就不用做过滤了?下载链接

        /// <summary>
        /// 导入CSV数据
        /// </summary>
        private static bool ImportCsvData(FileInfo file)
        {
            DataTable dt = GetCsvData(file);
            string s = dt.Rows[0][0] as string;
            if (s != "CS" && s != "C")
            {
                UnityEngine.Debug.LogError("客户端无需处理不带C的表格");
                return false; // 客户端无需处理不带C的表格
            }
            CreateByteData(file.Name.Replace(file.Extension, ""), dt);
            return true;
        }

2.第二步,填充数据到DataTable中,这里我用的是.csv表格(excel需要插件进行读取)这个其实就可以看作一个txt文件,中间用逗号隔开,这里我们用正则表达式过滤处理

        /// <summary>
        /// 可忽略引号中的","
        /// </summary>
        private static Regex pattern = new Regex(",(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))");
        /// <summary>
        /// 解析CSV数据到DataTable
        /// </summary>
        private static DataTable GetCsvData(FileInfo file)
        {
            DataTable dataTable = new DataTable();
            StreamReader streamReader = file.OpenText();
            string oneline;

            bool bFirstRow = true;
            int columnCount = 0;
            while ((oneline = streamReader.ReadLine()) != null)
            {
                string[] itemArray = pattern.Split(oneline);
                // 获取列数
                if (bFirstRow)
                {
                    foreach (var item in itemArray)
                    {
                        DataColumn dataColumn = new DataColumn(string.Format("F{0}", ++columnCount));
                        dataTable.Columns.Add(dataColumn);
                    }
                    bFirstRow = false;
                }
                //填充数据并加入到datatable中
                dataTable.Rows.Add(itemArray.Take(columnCount).ToArray());
            }
            streamReader.Close();
            return dataTable;
        }

3.第三步读取数据生产二进制文件与对应表格类,生产二进制文件就是将DataTable结构下的数据写到数据流中最终生成一个txt文件,因为如果要热更的话bundle只支持txt热更(.bytes这种后缀或者无后缀的不支持),生产对于表格类的话就可以下写出个模板来,对应字段名替换就行,其实就当作用程序写一个txt就可以了,只不过后缀是.cs

        //表头

        /// <summary>
        /// 将DataTable数据转换为二进制格式
        /// </summary>
        private static void CreateByteData(string fileName, DataTable dt)
        {
            try
            {
                //数据格式 行数 列数 二维数组每项的值 这里不做判断 都用string存储
                string[,] tableHeadArr = null;
                byte[] buffer = null;

                using (MemoryStream ms = new MemoryStream())
                using (BinaryWriter writer = new BinaryWriter(ms))
                {
                    //行数
                    int rows = dt.Rows.Count;
                    //列数
                    int columns = dt.Columns.Count;

                    tableHeadArr = new string[columns, HeaderRows];

                    writer.Write(rows - HeaderRows); //减去表头
                    for (int i = 0; i < rows; i++)
                    {
                        for (int j = 0; j < columns; j++)
                        {
                            if (i < HeaderRows)
                            {
                                tableHeadArr[j, i] = dt.Rows[i][j].ToString().Trim();
                            }
                            else
                            {
                                if (j > 0 && tableHeadArr[j, CSRow] != "CS" && tableHeadArr[j, CSRow] != "C")
                                {
                                    continue;
                                }
                                string type = tableHeadArr[j, TypeRow];
                                string value = dt.Rows[i][j].ToString().Trim();

                                switch (type.ToLower())
                                {
                                    case "int":
                                        writer.Write(string.IsNullOrWhiteSpace(value) ? 0 : int.Parse(value));
                                        break;
                                    case "long":
                                        writer.Write(string.IsNullOrWhiteSpace(value) ? 0 : long.Parse(value));
                                        break;
                                    case "short":
                                        writer.Write(string.IsNullOrWhiteSpace(value) ? (short)0 : short.Parse(value));
                                        break;
                                    case "float":
                                        writer.Write(string.IsNullOrWhiteSpace(value) ? 0 : float.Parse(value));
                                        break;
                                    case "byte":
                                        writer.Write(string.IsNullOrWhiteSpace(value) ? (byte)0 : byte.Parse(value));
                                        break;
                                    case "bool":
                                        writer.Write(string.IsNullOrWhiteSpace(value) ? false : bool.Parse(value));
                                        break;
                                    case "double":
                                        writer.Write(string.IsNullOrWhiteSpace(value) ? 0 : double.Parse(value));
                                        break;
                                    case "vector3":
                                        try
                                        {
                                            string[] array = value.Trim('\"').Split(',');
                                            float x = float.Parse(array[0]);
                                            float y = float.Parse(array[1]);
                                            float z = float.Parse(array[2]);
                                            writer.Write(x);
                                            writer.Write(y);
                                            writer.Write(z);
                                        }
                                        catch
                                        {
                                            Debug.LogError($"解析Vector3错误! str={value}");
                                            writer.Write(0f);
                                            writer.Write(0f);
                                            writer.Write(0f);
                                        }
                                        break;
                                    case "vector2":
                                        try
                                        {
                                            string[] array = value.Trim('\"').Split(',');
                                            float x = float.Parse(array[0]);
                                            float y = float.Parse(array[1]);
                                            writer.Write(x);
                                            writer.Write(y);
                                        }
                                        catch
                                        {
                                            Debug.LogError($"解析Vector2错误! str={value}");
                                            writer.Write(0f);
                                            writer.Write(0f);
                                        }
                                        break;
                                    default:
                                        writer.Write(value);
                                        break;
                                }
                            }
                        }
                    }
                    buffer = ms.GetBuffer();
                }
                CreateTableTableData(fileName, tableHeadArr, buffer);
                CreateTableTableCSharp(fileName, tableHeadArr, buffer);
            }
            catch (System.Exception ex)
            {
                Debug.LogError("Excel=>" + fileName + " Generate Failed:" + ex.Message);
            }
        }

        /// <summary>
        /// 生成Byte文件
        /// </summary>
        private static void CreateTableTableData(string fileName, string[,] dataArr, byte[] buffer)
        {
            string path = string.Format("{0}\\{1}", OutBytesFilePath, fileName + ".txt");
            FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write);
            BinaryWriter binaryWriter = new BinaryWriter(fs);
            binaryWriter.Write(buffer);
            binaryWriter.Flush();
            binaryWriter.Close();
        }


        /// <summary>
        /// 生成代码
        /// </summary>
        private static void CreateTableTableCSharp(string fileName, string[,] dataArr, byte[] buffer)
        {
            string templateTable = File.ReadAllText(Sourcepath + "CSharpTemplate/TemplateTable.txt");
            string templateColumn = File.ReadAllText(Sourcepath + "CSharpTemplate/TemplateColumn.txt");

            StringBuilder columnSb = new StringBuilder();
            StringBuilder ctorSb = new StringBuilder();
            for (int i = 0; i < dataArr.GetLength(0); i++)
            {
                if (i == 0)
                    continue;
                if (dataArr[i, CSRow] != "CS" && dataArr[i, CSRow] != "C")
                    continue;
                columnSb.Append(string.Format(templateColumn, dataArr[i, DescriptorRow], dataArr[i, TypeRow], dataArr[i, NameRow]));
                ctorSb.AppendLine($"            {dataArr[i, NameRow]} = reader.Read{ChangeTypeNameBinaryReader(dataArr[i, TypeRow])}();");
            }

            string entityContent = templateTable.Replace("{0}", fileName).Replace("{1}", columnSb.ToString()).Replace("{2}", ctorSb.ToString());

            using (FileStream fs = new FileStream(string.Format("{0}/{1}Table.cs", OutCSharpFilePath, fileName), FileMode.Create))
            {
                using (StreamWriter sw = new StreamWriter(fs))
                {
                    sw.Write(entityContent);
                }
            }
        }

4.最后就是写一个加载的方法,同样是用模板去搞


        private static void CreateTableLoadCSharp(List<string> list)
        {
            StringBuilder sb = new StringBuilder();
            string templateLoad = File.ReadAllText(Sourcepath + "CSharpTemplate/LoadData.txt");
            for (int i = 0; i < list.Count; i++)
            {
                sb.Append(templateLoad.Replace("{1}", list[i]));
            }
            string templateTable = File.ReadAllText(Sourcepath + "CSharpTemplate/DatasLoder.txt");

            string str = templateTable.Replace("{1}", sb.ToString());
            str = str.Replace("{2}", list.Count.ToString());
            using (FileStream fs = new FileStream($"{OutCSharpFilePath}/DatasLoder.cs", FileMode.Create))
            {
                using (StreamWriter sw = new StreamWriter(fs))
                {
                    sw.Write(str);
                }
            }
        }

5.写一个管理类,用于游戏启动加载表格数据,这个就不介绍了,就是加载数据。

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-01-24 11:15:39  更:2022-01-24 11:17:25 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 18:31:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码