前天看到Unreal 5.1引入了名为Iris的新的同步机制。过去三年一直在做UE4网络层的相关优化,看到这个新的实验特性,还是倍感振奋。在网上搜索了下,并没看到相关的中文资料。在Unreal开发者社区看到了如下文档:
《Experimental: Getting Started With Iris》(https://dev.epicgames.com/community/learning/tutorials/Xexv/unreal-engine-experimental-getting-started-with-iris)
于是在ChatGPT的帮助下,将其翻译成了中文(发现人工智能的翻译水平还是有待提高),有可能是全网比较正式的首篇Iris Replication的中文资料。
《实验特性:Iris入门》
在UE 5.1版本中,引擎提供了一个名为“Iris”的新的实验性同步机制,旨在提高引擎当前同步机制的性能、可扩展性和可维护性。这个新机制是可选的,并且向后兼容。然而,新旧两种同步机制存在一些重大的差异,因此本文将解释如何启用Iris以及可能需要对项目代码进行哪些更改。
启用Iris
默认情况下,Iris系统是关闭的,不会被编译。要将其包含在您的项目中,请将以下内容添加到您项目的*.Target.cs文件中:
代码语言:javascript复制// Enable iris if it is not already on by default
if (!bUseIris)
{
// If we enable Iris for a single target we also need to set the TargetBuildEnvironment to unique, as other projects in the solution might want it compiled out
BuildEnvironment = TargetBuildEnvironment.Unique;
bUseIris = true;
}
添加完毕后,在运行GenerateProjectFiles.bat之前,您可以验证Setup.bat是否成功运行。【译者注:对于已经完成编译的工程,原文这步操作似乎没有必要】
之后,当从源代码构建引擎时,Iris应该就会被编译了。值得注意的是,由于这个原因,使用引擎的二进制发行版目前无法启用该系统。
Iris在Unreal Build Tool的ModuleRules中添加了一个实用方法SetupIrisSupport(Target),以便更轻松地、可选地添加Iris所需的依赖项。要在模块中使用Iris,应该在该模块的*.Build.cs文件中调用该方法,该方法根据bUseIris决定添加相关依赖项。
项目的DefaultEngine.ini也必须修改以启用Iris。本文附带了一个处理启用和配置Iris的配置文件示例。
Iris提供了命令行参数“-UseIrisReplication=1”或“-UseIrisReplication=0”,允许使用者在运行时启用或禁用它。
最后值得注意的是,从UE5/Main的CL 22864286开始,默认情况下启用了Iris编译(即bUseIris=true),默认情况下在运行时仍然禁用Iris。为了在项目中启用Iris,仍然需要执行这里的其余步骤。此外,需要为项目启用实验性的Iris插件,并将"net.Iris.UseIrisReplication" CVar设置为1。
主要差异:
Iris尽可能地向后兼容当前同步机制,现有的属性复制和RPC定义已经支持。但是,Iris的工作仍在进行中,当前机制下的某些功能仍未提供,例如重放和异步加载。此外,这两个系统之间还存在一些较大的差异,可能需要对代码进行更改。
同步控制
Iris的一个关键设计是尽量减少同步系统和游戏玩法代码之间的交互。因此,新系统试图减少虚函数的使用,通过主动调用API函数来替代它们。以前依赖这些虚函数的功能,例如同步角色过滤、优先级和频率控制,现在都是使用API来控制。例如:
- IsNetRelevantFor()现在由Iris的过滤API管理。在角色的BeginReplication()函数中,可以使用bAlwaysRelevant、bNetUseOwnerRelevancy和bOnlyRelevantToOwner来设置这些过滤器。有关更多信息,可以查看NetObjectFilter.h,以及NetObjectGridFilter.h/.cpp,了解更高级过滤器的示例。
- Iris的源代码可以在“[EngineRoot]EngineSourceRuntimeExperimentalIrisCore”下找到。
- GetNetPriority()现在通过显式设置静态优先级或提供自定义优先级实现来管理。角色还可以使用提供的SphereNetObjectPrioritizer,默认情况下启用具有复制的WorldPosition的角色。有关更多信息,可以查看NetObjectPrioritizer.h,以及SphereNetObjectPrioritizer.h/.cpp。
还需要注意的是,Iris不支持Replication Graph。虽然Iris没有Replication Graph的“Node”概念,但新的网络对象过滤器和优先级设置器旨在替代Replication Graph提供的功能。
Iris还被设计为完全基于推送的。虽然可以在不使用Push Model的情况下使用Iris。当禁用Push Model时,Iris会回退到使用NetUpdateFrequency轮询所有复制的对象。但是,如果项目未启用Push Model,则可能会导致以下断言消息:"Trying to force enable Iris push model support when push model is disabled, falling back to optional path. Set Net.IsPushModelEnabled true."
要解决此问题,可以将“Net.IsPushModelEnabled”CVar 设置为 true,或者可以将“net.Iris.PushModelMode”CVar 设置为 0 或 2 以禁用或启用Push Model,同时仍允许它运行时可切换。在 5.1 中,net.Iris.PushModelMode 默认设置为 1,这将启用Push Model而无需在运行时切换它的选项,但自 CL 22482725 起,其默认值已更改为 2。
远程过程调用
在Iris中,远程过程调用(RPC)的工作方式大多与以前相同,但有一个关键的区别:RPC现在总是被推迟到,RPC依赖的连接更新之后发送。这意味着默认情况下,RPC总是在连接处理完所有同步状态数据之后执行。在之前的实现中,RPC和属性同步的执行顺序并不固定,并且在可靠和不可靠的RPC之间也存在差异。
子对象同步
以前,子对象同步依赖于角色实现虚函数AActor::ReplicateSubobjects。现在,Iris使用新添加的子对象注册列表来处理子对象同步。有关如何使用这些子对象列表的更多信息,请参见此处(https://forums.unrealengine.com/docs?topic=727659)。
未从UActorComponent派生的子对象需要实现虚方法RegisterReplicationFragments,以便向Iris注册其需要同步的属性和函数。可以在Gameplay Ability System的UAttributeSet(AttributeSet.h/.cpp)中看到其实现示例。
网络序列化
Iris引入的另一个重大变化是它使用NetSerializers来处理网络序列化。NetSerializers负责确定性地将单个类型的源数据转换为既有效地序列化为位流又可以通过位打包进行增量压缩的形式。它们还负责反向操作,从位流中反序列化数据并将其从其内部表示转换为原始源数据类型。
Iris已经支持了所有可以设置为同步的Unreal Engine基本类型,以及几个复杂类型。这些包括:
代码语言:javascript复制TArrays (of supported types)
TFastArrays
FName
FString
FVector and its quantized types
FRotator
FObject
FWeakObject
FSoftObject
FSoftObjectPath
FSoftClassPath
FFieldPath
FScriptInterface
FUniqueNetIdRepl
FGameplayAbilityTargetDataHandle
FGameplayEffectContextHandle
...and most other core engine types.
如果检测到不支持的类型,则运行时日志中应该会出现告警,例如“跳过不支持的属性”。
没有实现自定义序列化器的数据结构将使用通用结构序列化器,该序列化器使用结构中每个单独属性对应的序列化器。如果结构已经实现了自定义NetSerialize函数,但没有为Iris实现自定义NetSerializer,则描述符生成器将输出告警。要开始实现自定义NetSerializer,NetSerializer.h是一个很好的参考。但是,建议尽可能避免创建自定义序列化器。一个Iris规划中的功能是提供更详细的属性描述宏,描述如何同步属性,包括要使用的序列化器、该序列化器的参数和同步条件。目标是在不需要编写自定义序列化器的情况下,为项目提供更大的控制权,同时允许自动支持增量压缩等功能。
最后,虽然我们鼓励用户尝试这个新系统,但值得重申的是,Iris目前是实验性的。该系统的工作正在进行中,最新的更改可在UE5/Main中使用。我们不建议使用实验性功能发布项目,并且这些功能的API可能会发生变化。