虚幻引擎5引入Protocol Buffers 二(附工程源码)
前言
在编译完成Protobuf项目后(如何编译Protobuf项目),接下来即可将编译好的库,导入到项目工程中使用。本文主要讲解如何将Protobuf库导入到虚幻中,并使用。
本文选用的Protobuf版本是protobuf-3.21.12
操作
- 创建C++空白项目
- 在项目Soruce文件夹下,添加ThirdParty文件夹,用于导入第三方Protobuf库
- 添加用于导入库的模块文件夹,命名为UEProtobuf(名称随意)
- 在文件夹内添加include(用于存放头文件)和lib(用于存放库)文件夹
- 创建UEProtobuf.Build.cs文件,用于构建模块配置
- 拷贝Protobuf项目中的源码头文件到模块include文件夹中 src文件夹中,只需要拷贝后缀是.h和.inc文件即可,其他可删除
- 拷贝库文件到模块的lib文件夹中
- 配置Build.cs文件将如下内容拷贝到文件中
1using UnrealBuildTool;
2using System.IO;
3
4public class UEProtobuf : ModuleRules
5{
6 public UEProtobuf(ReadOnlyTargetRules Target) : base(Target)
7 {
8 Type = ModuleType.External;
9
10 PublicSystemLibraryPaths.Add(Path.Combine(ModuleDirectory, "lib"));
11
12 PublicIncludePaths.Add(Path.Combine(ModuleDirectory, "include"));
13
14 PublicSystemLibraries.Add("libprotobuf.lib");
15 PublicSystemLibraries.Add("libprotoc.lib");
16 }
17}
- 右键uproject文件,在菜单中选择刷新solution
使用Protobuf库
- 导入Protobuf库的模块
在项目的build文件中,加入模块UEProject
1//ProtobufToturial.Build.cs文件中截取代码
2PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "UEProtobuf" });
- 使用已经编译好的protobuf编译器(protoc.exe),将写好的protobuf文件编译成C++平台代码(这里需要你了解protobuf语法特点,并了解如何完成protobuf转换操作)。 protobuf文件内容如下:
1syntax = "proto3";
2message Phone {
3 int32 Number = 1;
4 string Name = 2;
5}
- 将生成的头文件和源文件拷贝到虚幻工程项目的source文件夹中(路径关系根据需求可调整)
- 在Rider中(VS操作基本一样),将头文件与源文件引入项目,操作如下:
- 测试代码
在Gamemode中添加指令函数,并在源文件中定义指令函数,编写如下测试代码。
头文件内容
1protected:
2 UFUNCTION(Exec)
3 void TestProtobuf();
源文件内容
1void AProtobufToturialGameModeBase::TestProtobuf()
2{
3 //声明Protobuf类型数据
4 Phone m_phone;
5 m_phone.set_number(100);
6 m_phone.set_name("这是一部iphone");
7
8 //输出数据
9 UE_LOG(LogTemp, Log, TEXT("%d"), m_phone.number());
10 //输出文本
11 UE_LOG(LogTemp, Log, TEXT("%s"), UTF8_TO_TCHAR(m_phone.name().c_str()));
12}
编译工程时,会出现如下错误
1 inlined_string_field.h(430): [C4668] 没有将“GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE”定义为预处理器宏,用“0”替换“#if/#elif”
2 inlined_string_field.h(430): [C4668] 没有将“GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE”定义为预处理器宏,用“0”替换“#if/#elif”
3 Microsoft.MakeFile.targets(45, 5): [MSB3073] 命令“"D:\Program Files\Epic Games\UE_5.1\Engine\Build\BatchFiles\Build.bat" ProtobufToturialEditor Win64 Development -Project="D:\Projectes\UE\ProtobufToturial\ProtobufToturial.uproject" -WaitMutex -FromMsBuild”已退出,代码为 6。
这个错误是因为需要在项目中配置预处理宏,用来管理是启用调试和非调试。修改方法如下:
到inlined_string_field.h文件中(双击错误跳转),将代码进行修改,参照如下:
1#if GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE
2 lhs->get_mutable()->swap(*rhs->get_mutable());
3 if (!lhs_arena_dtor_registered && rhs_arena_dtor_registered) {
4 lhs_msg->OnDemandRegisterArenaDtor(lhs_arena);
5 } else if (lhs_arena_dtor_registered && !rhs_arena_dtor_registered) {
6 rhs_msg->OnDemandRegisterArenaDtor(rhs_arena);
7 }
改后
1//调整此段
2#ifdef GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE
3 lhs->get_mutable()->swap(*rhs->get_mutable());
4 if (!lhs_arena_dtor_registered && rhs_arena_dtor_registered) {
5 lhs_msg->OnDemandRegisterArenaDtor(lhs_arena);
6 } else if (lhs_arena_dtor_registered && !rhs_arena_dtor_registered) {
7 rhs_msg->OnDemandRegisterArenaDtor(rhs_arena);
8 }
再次编译即可通过
- 运行查看结果
启用工程,将地图模式设置为项目Gamemode,通过唤出指令进行测试,即可得到测试结果。
1Cmd: TestProtobuf
2LogTemp: 100
3LogTemp: 这是一部iphone
引擎版本:5.1.1
Protobuf版本:3.21.12
此模块UE4和UE5均可使用,如果你需要应用到自己工程,只需要将ThirdParty拷走,重新编译即可。
网盘资源 提取码: 4dcm