Unity | 集成 Protobuf(proto 转 cs 插件及序列化与反序列化)

2024-04-25 18:12

本文主要是介绍Unity | 集成 Protobuf(proto 转 cs 插件及序列化与反序列化),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 添加 dll

1. 下载 protobuf 源码

根据需要下载 protobuf 指定版本的源码,这里以 v3.21.12(protobuf-csharp-3.21.12.zip)为例:

下载地址:「https://github.com/protocolbuffers/protobuf/releases」

2. 下载 Visual Studio 2022

曾尝试使用 Visual Studio 2021 版本编译,但是会报错,更新版本后,即可编译成功

下载地址:「https://visualstudio.microsoft.com/zh-hans/downloads/」

3. 编译 dll

1. 使用 Visual Studio 2022 打开 protobuf 项目中的 Google.Protobuf.sln

2. 编译模式选择:Release

3. Google.Protobuf 右键选择生成 Google.Protobuf

4. 拷贝 dll

编译生成的 dll 在 csharp/src/Google.Protobuf/bin/Release 目录下

将 net45 目录下所有的 dll 文件拷贝到 Unity 指定目录中

2. proto 转 cs

1. 下载编译器

在 protobuf 源码链接中下载对应的平台的编译器(mac: protoc-21.12-osx-x86_64.zip,windows:protoc-21.12-win64.zip)

2. 命令行转换

在终端中进入到编译器所在的目录:bin/protoc,然后执行对应的命令

  • 转换指定 proto 文件:

./protoc ./Addressbook.proto --csharp_out=./
  • 转换指定目录下所有 proto 文件:

./protoc ./*.proto --csharp_out=./

将生成的 cs 文件,放入 Unity 项目中

3. 插件转换

除了直接使用命令行外,也可以在 Unity 中编写插件,利用 Process 执行命令行,转换 proto 文件:

public class ProtoToClass
{[MenuItem("RavenKit/Proto To Class")]public static void GenerateClassFromProto(){string rootPath = Environment.CurrentDirectory;string protoPath = Path.Combine(rootPath, "Proto/");string protoc = Path.Combine(protoPath,RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "protoc.exe" : "protoc");string outPath = EditorPrefs.GetString(Application.identifier + "-ProtoClassPath");if (string.IsNullOrEmpty(outPath)){outPath = EditorUtility.OpenFolderPanel("选择存储目录", Application.dataPath, "");if (!string.IsNullOrEmpty(outPath)){EditorPrefs.SetString(Application.identifier + "-ProtoClassPath", outPath);}}string[] protoFiles = Directory.GetFiles(protoPath, "*.proto");foreach (var variable in protoFiles){string argument = $"--csharp_out={outPath} --proto_path={protoPath} {variable}";Run(protoc, argument);}AssetDatabase.Refresh();}public static Process Run(string exe, string arguments){ProcessStartInfo info = new ProcessStartInfo{FileName = exe,Arguments = arguments,CreateNoWindow = true,UseShellExecute = false,RedirectStandardOutput = true,RedirectStandardError = true,};Process process = Process.Start(info);process.WaitForExit();if (process.ExitCode != 0){Debug.LogError($"Failed to Run {arguments}. Exit code: " + process.ExitCode);}return process;}
}

3. 序列化及反序列化

使用方法在官方的源码中也有详细的示例:

byte[] bytes;
// Create a new person
Person person = new Person
{Id = 1,Name = "Foo",Email = "foo@bar",Phones = { new Person.Types.PhoneNumber { Number = "555-1212" } }
};
using (MemoryStream stream = new MemoryStream())
{// Save the person to a streamperson.WriteTo(stream);bytes = stream.ToArray();
}
Person copy = Person.Parser.ParseFrom(bytes);AddressBook book = new AddressBook
{People = { copy }
};
bytes = book.ToByteArray();
// And read the address book back again
AddressBook restored = AddressBook.Parser.ParseFrom(bytes);// The message performs a deep-comparison on equality:
if (restored.People.Count != 1 || !person.Equals(restored.People[0]))
{throw new Exception("There is a bad person in here!");
}

反序列化时,除了使用 ParseFrom 方法

AddressBook.Parser.ParseFrom(bytes) 

也可以使用 MergeFrom 方法

message.MergeFrom(data);

将序列化和反序列化封装为通用的函数:

public static class ProtobufUtility
{/// <summary>/// 序列化/// </summary>/// <param name="msg"></param>/// <returns></returns>public static byte[] Serialize(IMessage message){using (MemoryStream stream = new MemoryStream()){message.WriteTo(stream);byte[] result = ms.ToArray();return result;}}/// <summary>/// 反序列化/// </summary>/// <typeparam name="T"></typeparam>/// <param name="data"></param>/// <returns></returns>public static T Deserialize<T>(byte[] data) where T : IMessage, new(){T message = new T();// message = (T)message.Descriptor.Parser.ParseFrom(data);message.MergeFrom(data);return msg;}
}

这篇关于Unity | 集成 Protobuf(proto 转 cs 插件及序列化与反序列化)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/935420

相关文章

SpringCloud集成AlloyDB的示例代码

《SpringCloud集成AlloyDB的示例代码》AlloyDB是GoogleCloud提供的一种高度可扩展、强性能的关系型数据库服务,它兼容PostgreSQL,并提供了更快的查询性能... 目录1.AlloyDBjavascript是什么?AlloyDB 的工作原理2.搭建测试环境3.代码工程1.

SpringBoot使用注解集成Redis缓存的示例代码

《SpringBoot使用注解集成Redis缓存的示例代码》:本文主要介绍在SpringBoot中使用注解集成Redis缓存的步骤,包括添加依赖、创建相关配置类、需要缓存数据的类(Tes... 目录一、创建 Caching 配置类二、创建需要缓存数据的类三、测试方法Spring Boot 熟悉后,集成一个外

Docker集成CI/CD的项目实践

《Docker集成CI/CD的项目实践》本文主要介绍了Docker集成CI/CD的项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录一、引言1.1 什么是 CI/CD?1.2 docker 在 CI/CD 中的作用二、Docke

SpringBoot集成SOL链的详细过程

《SpringBoot集成SOL链的详细过程》Solanaj是一个用于与Solana区块链交互的Java库,它为Java开发者提供了一套功能丰富的API,使得在Java环境中可以轻松构建与Solana... 目录一、什么是solanaj?二、Pom依赖三、主要类3.1 RpcClient3.2 Public

SpringBoot3集成swagger文档的使用方法

《SpringBoot3集成swagger文档的使用方法》本文介绍了Swagger的诞生背景、主要功能以及如何在SpringBoot3中集成Swagger文档,Swagger可以帮助自动生成API文档... 目录一、前言1. API 文档自动生成2. 交互式 API 测试3. API 设计和开发协作二、使用

SpringBoot如何集成Kaptcha验证码

《SpringBoot如何集成Kaptcha验证码》本文介绍了如何在Java开发中使用Kaptcha生成验证码的功能,包括在pom.xml中配置依赖、在系统公共配置类中添加配置、在控制器中添加生成验证... 目录SpringBoot集成Kaptcha验证码简介实现步骤1. 在 pom.XML 配置文件中2.

IDEA常用插件之代码扫描SonarLint详解

《IDEA常用插件之代码扫描SonarLint详解》SonarLint是一款用于代码扫描的插件,可以帮助查找隐藏的bug,下载并安装插件后,右键点击项目并选择“Analyze”、“Analyzewit... 目录SonajavascriptrLint 查找隐藏的bug下载安装插件扫描代码查看结果总结Sona

Java中JSON字符串反序列化(动态泛型)

《Java中JSON字符串反序列化(动态泛型)》文章讨论了在定时任务中使用反射调用目标对象时处理动态参数的问题,通过将方法参数存储为JSON字符串并进行反序列化,可以实现动态调用,然而,这种方式容易导... 需求:定时任务扫描,反射调用目标对象,但是,方法的传参不是固定的。方案一:将方法参数存成jsON字

2. c#从不同cs的文件调用函数

1.文件目录如下: 2. Program.cs文件的主函数如下 using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using System.Windows.Forms;namespace datasAnalysis{internal static

【区块链 + 人才服务】区块链集成开发平台 | FISCO BCOS应用案例

随着区块链技术的快速发展,越来越多的企业开始将其应用于实际业务中。然而,区块链技术的专业性使得其集成开发成为一项挑战。针对此,广东中创智慧科技有限公司基于国产开源联盟链 FISCO BCOS 推出了区块链集成开发平台。该平台基于区块链技术,提供一套全面的区块链开发工具和开发环境,支持开发者快速开发和部署区块链应用。此外,该平台还可以提供一套全面的区块链开发教程和文档,帮助开发者快速上手区块链开发。