简易php企业网站源码/太原seo网站优化

简易php企业网站源码,太原seo网站优化,wordpress除了首页全是404,没有公司 接单做网站前言 在Unity游戏开发中,高效、快速、安全地读取配置数据是一项重要需求。本文介绍一种完整的解决方案——使用Protobuf二进制格式(Pb2)存储和读取游戏数据,并详细分享实现全流程的Unity工具。 一、技术流程概览 实现Unity读取…

前言

在Unity游戏开发中,高效、快速、安全地读取配置数据是一项重要需求。本文介绍一种完整的解决方案——使用Protobuf二进制格式(Pb2)存储和读取游戏数据,并详细分享实现全流程的Unity工具。

一、技术流程概览

实现Unity读取Pb2二进制数据的流程如下:

  1. Excel设计数据表
  2. Excel转Proto文件
  3. Proto文件转C#类
  4. Excel数据序列化为Pb2二进制文件
  5. Unity中加载Pb2数据文件

二、具体实现步骤

1. Excel设计数据表

数据表应遵循特定的格式规范:

  • 第一行:字段注释
  • 第二行:字段名(英文变量名)
  • 第三行:字段数据类型(例如int32、string)
  • 第四行及以下:数据内容

2. Excel转Proto文件

使用自定义编辑器工具自动将Excel表转换为.proto文件。

关键代码ProtoGenerator.cs

private void GenerateProtoFile(){FileInfo fileInfo = new FileInfo(excelFilePath);if (!fileInfo.Exists){Debug.LogError("Excel 文件不存在: " + excelFilePath);return;}// 确保输出目录存在if (!Directory.Exists(outputFolder)){Directory.CreateDirectory(outputFolder);}// 定义 .proto 文件头部信息string protoContent = "syntax = \"proto3\";\n";protoContent += "package GameDataProto;\n\n";using (ExcelPackage package = new ExcelPackage(fileInfo)){// 遍历所有工作表,每个工作表生成一个 messageforeach (ExcelWorksheet worksheet in package.Workbook.Worksheets){string messageName = worksheet.Name;protoContent += $"message {messageName} {{\n";// 假定第一行为注释,第二行为变量名,第三行为类型int colCount = worksheet.Dimension.Columns;int fieldIndex = 1;for (int col = 1; col <= colCount; col++){object commentObj = worksheet.Cells[1, col].Value;object variableNameObj = worksheet.Cells[2, col].Value;object typeObj = worksheet.Cells[3, col].Value;if (variableNameObj == null || typeObj == null)continue;string comment = commentObj != null ? commentObj.ToString().Trim() : "";string variableName = variableNameObj.ToString().Trim();string type = typeObj.ToString().Trim();if (!string.IsNullOrEmpty(comment)){protoContent += $"    // {comment}\n";}protoContent += $"    {type} {variableName} = {fieldIndex};\n";fieldIndex++;}protoContent += "}\n\n";}}string protoFilePath = Path.Combine(outputFolder, "GameDataProto.proto");Editor.EditorHelper.WriteAllText(protoFilePath, protoContent);Debug.Log($"生成 .proto 文件: {protoFilePath}");}
  • 通过Unity Editor菜单打开窗口,选择Excel文件与输出目录,自动生成.proto文件。
3. Proto文件转C#类

根据生成的.proto文件,自动生成对应的C#数据类。

关键代码ProtoToCSharpGenerator.cs

  • 自动解析proto协议,生成继承自DataInfo的数据类与继承自BaseGameData的容器类GameData
[ProtoBuf.ProtoContract]public class DataInfo{[ProtoBuf.ProtoIgnore]public int id;}public class BaseGameData{/// <summary>/// 使用反射将加载到的表格数据存储到当前 GameData 实例中。/// 例如,加载到的 List<CharacterInfo> 会赋值给属性名为 CharacterInfo 的属性,/// 要求属性类型必须为 List<T>,T 与传入数据类型一致。/// </summary>/// <typeparam name="T">表格数据的元素类型</typeparam>/// <param name="tableData">加载到的表格数据列表</param>public void SetTableData<T>(List<T> tableData){// 查找当前实例中类型为 List<T> 的公共属性var property = this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(p => p.PropertyType == typeof(List<T>));if (property != null){property.SetValue(this, tableData);Debug.Log($"成功将 {typeof(T).Name} 数据加载到 {this.GetType().Name} 中。");}else{Debug.LogError($"在 {this.GetType().Name} 中未找到类型为 List<{typeof(T).Name}> 的属性。");}}public T GetDataByID<T>(int id) where T : DataInfo{var containerType = GetType();// 改为搜索公共字段,而非属性var field = containerType.GetFields(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(f => f.FieldType == typeof(List<T>));if (field != null){var list = field.GetValue(this) as List<T>;if (list != null){return list.FirstOrDefault(item => item.id == id);}}return default(T);}}
 // 固定使用的命名空间string packageName = "Reacool.Core.DataTable";List<string> messageNames = new List<string>();string[] lines = Reacool.Editor.EditorHelper.ReadAllLines(protoFilePath);bool isMessage = false;bool isEnum = false;StringBuilder sb = new StringBuilder();// 文件头注释和 using 声明sb.AppendLine("// 通过 .proto 文件自动生成的 C# 文件,请勿手动修改");sb.AppendLine("using System.Collections.Generic;");sb.AppendLine();// 开始生成代码,强制命名空间为 Reacool.Core.DataTablesb.AppendLine($"namespace {packageName}");sb.AppendLine("{");// 解析 .proto 文件内容for (int i = 0; i < lines.Length; i++){string line = lines[i].Trim();// 忽略 package 声明(固定命名空间)if (line.StartsWith("package")){continue;}else if (line.StartsWith("//")){sb.AppendLine("    " + line);}else if (line.StartsWith("message")){isMessage = true;var match = Regex.Match(line, @"message\s+(\w+)");if (match.Success){string messageName = match.Groups[1].Value;if (!messageNames.Contains(messageName))messageNames.Add(messageName);// 表格类继承 DataInfosb.AppendLine("    [ProtoBuf.ProtoContract]");sb.AppendLine($"    public class {messageName} : DataInfo");sb.AppendLine("    {");// 在每个 message 里,自动插入 idProxy 属性,替代基类 id 做序列化sb.AppendLine("        [ProtoBuf.ProtoMember(1)]");sb.AppendLine("        public int idProxy");sb.AppendLine("        {");sb.AppendLine("            get => base.id;");sb.AppendLine("            set => base.id = value;");sb.AppendLine("        }");}}else if (line.StartsWith("enum")){isEnum = true;var match = Regex.Match(line, @"enum\s+(\w+)");if (match.Success){string enumName = match.Groups[1].Value;sb.AppendLine("    public enum " + enumName);sb.AppendLine("    {");}}else if (line.StartsWith("}")){if (isMessage || isEnum){sb.AppendLine("    }");isMessage = false;isEnum = false;}}else if (string.IsNullOrEmpty(line)){sb.AppendLine();}else if (isMessage){// 解析 message 内字段,如 "repeated type name = id;"var fieldMatch = Regex.Match(line, @"(repeated\s+)?(\w+)\s+(\w+)\s*=\s*(\d+);");if (fieldMatch.Success){bool isArray = !string.IsNullOrEmpty(fieldMatch.Groups[1].Value);string fieldType = fieldMatch.Groups[2].Value;string fieldName = fieldMatch.Groups[3].Value;int fieldId = int.Parse(fieldMatch.Groups[4].Value);// 跳过 id 属性,因为我们已经用 idProxy 代替if (fieldName.Equals("id", System.StringComparison.OrdinalIgnoreCase)){continue;}// 简单转换 Protobuf 基本类型为 C# 类型if (fieldType == "int32") fieldType = "int";else if (fieldType == "int64") fieldType = "long";sb.AppendLine($"        [ProtoBuf.ProtoMember({fieldId})]");sb.AppendLine($"        public {fieldType}{(isArray ? "[]" : "")} {fieldName};");}}else if (isEnum){sb.AppendLine("        " + line.Replace(';', ','));}
4. Excel数据序列化为Pb2二进制文件

使用工具将Excel表中数据自动序列化为Protobuf二进制格式。

关键代码ProtobufBytesGenerator.cs

  • 自动读取Excel文件,解析工作表,并序列化为Pb2格式,存储成.bytes文件。
FileInfo excelFile = new FileInfo(excelFilePath);using (ExcelPackage package = new ExcelPackage(excelFile)){// 通过反射获取 GameData 类型的所有公共实例字段Type gameDataType = typeof(T);FieldInfo[] fields = gameDataType.GetFields(BindingFlags.Public | BindingFlags.Instance);foreach (FieldInfo field in fields){// 仅处理 List<T> 类型的字段if (field.FieldType.IsGenericType &&field.FieldType.GetGenericTypeDefinition() == typeof(List<>)){Type elementType = field.FieldType.GetGenericArguments()[0];// 约定工作表名称与元素类型名称相同(如 CharacterInfo、AudioInfo 等)string sheetName = elementType.Name;var worksheet = package.Workbook.Worksheets[sheetName];if (worksheet == null){Debug.LogWarning("未找到工作表:" + sheetName + ",跳过。");continue;}// 调用通用解析方法 ParseSheet<T> 将工作表数据转为 List<T>MethodInfo method = typeof(BinaryGenerator).GetMethod("ParseSheet", BindingFlags.NonPublic | BindingFlags.Static);MethodInfo genericMethod = method.MakeGenericMethod(elementType);object listObj = genericMethod.Invoke(null, new object[] { worksheet });// 输出文件路径:以工作表名称命名的二进制文件(例如 CharacterInfo.bytes)string outputFilePath = Path.Combine(outputFolder, sheetName + ".bytes");using (FileStream fs = new FileStream(outputFilePath, FileMode.Create)){Serializer.Serialize(fs, listObj);}Debug.Log("生成二进制文件成功:" + outputFilePath);}}}
5. Unity中加载Pb2数据文件

通过DataTableManager读取Pb2二进制文件并反序列化。

关键代码DataTableManager.csBaseGameData.cs

  • 使用泛型反射动态加载二进制数据,存入BaseGameData对象中,统一管理。
 /// <summary>/// 保存二进制数据/// </summary>/// <param name="fileData"></param>/// <typeparam name="T"></typeparam>public void ProcessByteData<T,T2>(byte[] fileData)where T : DataInfo where T2 : BaseGameData{if (fileData == null || fileData.Length == 0){Debug.LogError("传入的数据为空!");return;}// 根据类型名称生成对应的字段名:例如 "CharacterInfo" -> "characterInfos"string typeName = typeof(T).Name;string fieldName = char.ToLowerInvariant(typeName[0]) + typeName.Substring(1) + "s";// 利用反射获取全局 GameData 实例中对应的公共字段var field = typeof(T2).GetField(fieldName, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);if (field == null){Debug.LogWarning($"GameData 中未找到对应字段:{fieldName}");return;}// 检查该字段是否已经有数据加载,若有数据,则跳过加载var existingData = field.GetValue(this.GameData) as System.Collections.IList;if (existingData != null && existingData.Count > 0){Debug.Log($"{typeName} 数据已加载,跳过加载。");return;}// 反序列化传入的 bytes 数据List<T> listObj = null;try{using (var ms = new System.IO.MemoryStream(fileData)){listObj = ProtoBuf.Serializer.Deserialize<List<T>>(ms);}}catch (System.Exception ex){Debug.LogError($"解析 {typeName} 数据失败:{ex.Message}");return;}// 将解析后的数据存入 GameData 中对应的字段field.SetValue(this.GameData, listObj);Debug.Log($"成功加载 {typeName} 数据到 GameData.{fieldName}");}

三、关键代码解析

  • Excel转二进制数据:使用EPPlus解析Excel文件,序列化数据为二进制格式。
  • 数据反序列化:利用Protobuf库,将二进制数据反序列化为C#对象。
  • 反射自动加载:利用C#反射特性,自动匹配数据字段和数据类型,简化数据加载过程。

四、总结

本文提供了一整套基于Unity引擎的Protobuf(Pb2)数据管理流程,从Excel设计、数据转换、代码生成到数据加载,自动化程度高且扩展性强。通过本文分享的工具与方法,开发者可以高效地实现Unity项目的数据管理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/73266.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

stm32-IIC

i^2c,iiCBus,集成电路总线&#xff0c;同步串行半双工通信总线方式 sck:时钟同步信号 SDA:发送数据 GND&#xff1a;接地 通信对象&#xff1a;芯片与芯片 主从应答方式&#xff1a; SDA&#xff1a;数据总线 SCL&#xff1a;时钟总线 在硬件设计中&#xff1a; 上拉电阻&#…

`chromadb` 是什么

chromadb 是什么 chromadb 是一个开源的向量数据库,它专门用于存储、索引和查询向量数据。在处理自然语言处理(NLP)、计算机视觉等领域的任务时,通常会将文本、图像等数据转换为向量表示,而 chromadb 可以高效地管理这些向量,帮助开发者快速找到与查询向量最相似的向量数…

Centos操作系统安装及优化

Centos操作系统安装及优化 零、环境概述 主机名 centos版本 cpu 内存 Vmware版本 ip地址 test CentOS Linux release 7.6.1810 (Core) 2C 2G 15.5.1 10.0.0.10 一、介质下载 1、7.6版本下载 CentOS7.6标准版下载链接: https://archive.kernel.org/centos-vault/7.6.1810/i…

mac上安装nvm及nvm的基本语法使用!!

种一棵树&#xff0c;最好是十年前&#xff0c;其次是现在&#xff01;想要改变&#xff0c;从此刻开始&#xff0c;一切都不晚&#xff01; 目录 nvm是什么&#xff1f;前提条件&#xff1a;安装homebrew如果系统已经有node版本&#xff1a;在mac上安装nvm&#xff1a;用nvm安…

Kubernetes(k8s)-Pod亲和性(Affinity)和反亲和性(Anti-affinity)

作者介绍&#xff1a;简历上没有一个精通的运维工程师。请点击上方的蓝色《运维小路》关注我&#xff0c;下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 我们上一章介绍了Docker基本情况&#xff0c;目前在规模较大的容器集群基本都是Kubernetes&#xff0c;但是K…

ESP32-C3物联网方案,智能设备创新升级,无线交互控制通信应用

在物联网技术迅猛发展的今天&#xff0c;各类智能设备如雨后春笋般涌现&#xff0c;深度融入我们生活与工作的各个角落&#xff0c;物联网正以一种前所未有的速度改变着我们的世界。 想象一下&#xff0c;清晨&#xff0c;当第一缕阳光洒进房间&#xff0c;智能窗帘自动缓缓拉…

Python自动化测试 之 DrissionPage 的下载、安装、基本使用详解

Python自动化测试 之 DrissionPage 使用详解 &#x1f3e1;前言&#xff1a;一、☀️DrissionPage的基本概述二、 &#x1f5fa;️环境安装2.1 ✅️️运行环境2.2 ✅️️一键安装 三、&#x1f5fa;️快速入门3.1 页面类&#x1f6f0;️ChromiumPage&#x1f6eb; SessionPage&…

【操作系统安全】任务3:Linux 网络安全实战命令手册

目录 一、基础网络信息获取 1. 网络接口配置 2. 路由表管理 3. 服务端口监控 二、网络监控与分析 1. 实时流量监控 2. 数据包捕获 3. 网络协议分析 三、渗透测试工具集 1. 端口扫描 2. 漏洞利用 3. 密码破解 四、日志审计与分析 1. 系统日志处理 2. 入侵检测 3…

社群经济4.0时代:开源链动模式与AI技术驱动的电商生态重构

摘要&#xff1a;在Web3.0技术浪潮与私域流量红利的双重驱动下&#xff0c;电商行业正经历从"流量收割"到"用户深耕"的范式转变。本文基于社群经济理论框架&#xff0c;结合"开源链动21模式"、AI智能名片、S2B2C商城小程序源码等创新工具&#x…

从技术架构和生态考虑,不是单纯的配置优化,还有哪些方式可以提高spark的计算性能

从技术架构和生态系统层面提升Spark的计算性能&#xff0c;可采取以下核心策略&#xff1a; 一、计算模型重构与执行引擎升级 1. 弹性分布式数据集&#xff08;RDD&#xff09;的血统优化 通过RDD的Lineage&#xff08;血统&#xff09;机制实现容错时&#xff0c;采用增量式…

AI对软件工程(software engineering)的影响在哪些方面?

AI对软件工程&#xff08;software engineering&#xff09;的影响是全方位且深远的&#xff0c;它不仅改变了传统开发流程&#xff0c;还重新定义了工程师的角色和软件系统的构建方式。以下是AI影响软件工程的核心维度&#xff1a; 一、开发流程的智能化重构 需求工程革命 • …

数据库取证分析

目录 一.多表关联 1.一对多联结 2.子查询 二.数据库示例分析 1.多表关联 三.选择SQL分析的原因 四.数据库概述 五.SQL语言 一.多表关联 1.一对多联结 2.子查询 二.数据库示例分析 1.多表关联 三.选择SQL分析的原因 四.数据库概述 五.SQL语言 1.select 字段

Docker 部署 Graylog 日志管理系统

Docker 部署 Graylog 日志管理系统 前言一、准备工作二、Docker Compose 配置三、启动 Graylog 服务四、访问 Graylog Web 界面总结 前言 Graylog 是一个开源的日志管理平台&#xff0c;专为实时日志收集、分析和可视化设计。它支持强大的搜索功能&#xff0c;并且与 Elastics…

Matlab2024a免费版下载教程

Matlab是一个高性能的数学计算与仿真软件&#xff0c;广泛应用于科学计算、数据分析、算法开发以及工程绘图等多个领域。它提供了强大的矩阵运算能力、丰富的内置函数库以及灵活的编程环境&#xff0c;使得用户能够高效地解决复杂的数学问题。本文&#xff0c;我将为大家详细介…

网络运维学习笔记(DeepSeek优化版) 022 HCIP-Datacom路由概念、BFD协议详解与OSPF第一课

文章目录 路由概念、BFD协议详解与OSPF第一课一、路由协议优先级与选路原则1.1 路由协议优先级对照表1.2 路由选路核心原则 二、BFD&#xff08;Bidirectional Forwarding Detection&#xff0c;双向转发检测&#xff09;的配置与应用2.1 双向心跳探测&#xff08;双端配置&…

【基础】Windows 中通过 VSCode 使用 GCC 编译调试 C++

准备 安装 VSCode 及 C 插件。通过 MSYS2 安装 MinGW-w64 工具链&#xff0c;为您提供必要的工具来编译代码、调试代码并配置它以使用IntelliSense。参考&#xff1a;Windows 中的 Linux 开发工具链 验证安装&#xff1a; gcc --version g --version gdb --version三个核心配…

python机器学习——新手入门学习笔记

一&#xff0c;概论 1.什么是机器学习 定义&#xff1a; 机器学习是从数据中自动分析获得模型&#xff0c;并利用模型对未知数据进行预测。 其实就是通过问题和数据&#xff0c;发现规律&#xff0c;并进行预测&#xff0c;与人脑相似。目的就是从历史数据当中获得规律&#x…

Packaging Process

Packaging Process 软包装流程&#xff0c;在我们自动化设备的情况下&#xff0c;最后实现自动化工具 一小盒2袋&#xff0c;一大盒3小盒&#xff0c;一大盒6袋

地理信息系统(GIS)在智慧城市中的40个应用场景案例

在智慧城市发展进程中&#xff0c;地理信息系统&#xff08;GIS&#xff09;作为关键技术之一&#xff0c;正扮演着不可或缺的角色&#xff0c;堪称智慧城市的神经中枢。通过空间数据分析优化城市管理&#xff0c;GIS技术为智慧城市的构建提供了强大的支持。 本文分享了GIS在智…

【蓝桥杯】每日练习 Day11 逆序对问题和多路归并

目录 前言 超快速排序 分析 代码 小朋友排队 分析 代码 鱼塘钓鱼 分析 代码 前言 本来计划今天写五道题的&#xff0c;结果计划赶不上变化&#xff0c;谁能告诉我我的时间都去哪了。。。 今天给大家带来三道题目&#xff0c;两道逆序对问题&#xff0c;分别用归并排…