属性复制

有关如何复制Actor属性的详细信息。

Choose your operating system:

Windows

macOS

Linux

每个Actor维护一个全属性列表,其中包含 Replicated 说明符 。每当复制的属性值发生变化时,服务器会向所有客户端发送更新。客户端会将其应用到Actor的本地版本上。这些更新只会来自服务器,客户端永远不会向服务器或其他客户端发送属性更新。

我们不推荐在客户端上更改复制的变量值。该值将始终与服务器端的值不一致,直到服务器下一次侦测到变更并发送更新为止。如果服务器版本的属性不是经常更新,那客户端就需要等待很长时间才能被纠正。

Actor属性复制可靠。这意味着,Actor的客户端版本的属性最终将反映服务器上的值,但客户端不必接受服务器上某个属性的每一个单独变更。例如,如果一个整数属性的值快速从100变成200,然后又变成了300,客户端将最终接受一个值为300的变更,但客户端不一定会知道这个值曾经变成过200。

设置要复制的属性

要复制属性,您需要做几件事情: 在定义属性的Actor类标头处,您需要确保将"replicated"关键字作为UPROPERTY声明的参数之一:

class ENGINE_API AActor : public UObject
{
    UPROPERTY( replicated )
    AActor * Owner;
};

在Actor类的实现过程中,需要实现GetLifetimeReplicatedProps函数:

void AActor::GetLifetimeReplicatedProps( TArray< FLifetimeProperty > & OutLifetimeProps ) const
{
    DOREPLIFETIME( AActor, Owner );
}

在Actor的构造函数中,确保将bReplicates标记设置为true:

AActor::AActor( const class FPostConstructInitializeProperties & PCIP ) : Super( PCIP )
{ 
    bReplicates = true;
}

对于当前实例化的Actor类型的每个副本,成员变量"Owner"现在将同步到所有连接的客户端(在本例中为基础Actor类)。

网络更新优化

数据驱动型网络更新频率

Actor将观察在其"NetUpdateFrequency"变量中设置的最大更新频率。通过在不太重要或不太频繁变化的Actor上降低该变量,网络更新可以变得更高效,同时在有限带宽的场景中可能会带来更流畅的游戏体验。常见的更新频率值为:对于重要且不可预知的Actor,例如在射击游戏中由玩家控制的角色,为10(每0.1秒更新一次);对于行动缓慢的角色,例如在合作类游戏中由AI控制的怪物,为5(每0.2秒更新一次),对于游戏进程不是很重要但仍通过网络同步的以及/或者由服务器端逻辑控制因而需要复制的后台Actor,为2(每0.5秒更新一次)。

自适应型网络更新频率

在默认情况下,该功能是关闭的。将控制台变量 net.UseAdaptiveNetUpdateFrequency 设置到 1 可以将其激活。

通过自适应型网络更新频率,我们可以节省CPU周期,这些CPU周期通常会在没有任何实际更改的情况下多次尝试复制Actor而浪费掉。当启用了该功能时,系统将根据各个Actor的更新是否有意义,动态调整其更新频率。在该上下文中,"有意义的"更新为初始化了Actor、添加或删除了子对象(即拥有的组件)、或者更改了Actor上或其任何子对象上复制字段值的任何更新。每个Actor可能的更新速率范围由Actor本身的两个变量决定:"NetUpdateFrequency"和"MinNetUpdateFrequency"。"NetUpdateFrequency"表示Actor每秒尝试更新自己的最大次数,而"MinNetUpdateFrequency"表示每秒尝试更新的最小次数。使用该功能可以大大提高复制性能。

(高级)更新频率降低算法

在更新尝试期间,Actor将确定最近一次有意义的更新发送到现在有多长时间,如果它们发送了有意义的更新,将记录新的时间。如果考虑进行更新的Actor超过2秒没有发送有意义的更新,那么它将开始降低更新频率,在没有发送有意义的更新的情况下,更新频率将在7秒后达到最小。例如,如果更新延迟在0.1秒到0.6秒之间的Actor在3秒内没有任何有意义的更新,那么它将在0.2秒内尝试下一次更新。

(高级)更新频率增加算法

在发送一个有意义的更新之后,Actor将安排下一个更新发生的时间,使其比前两次有意义的更新之间的时间短30%,并且处于最小更新频率与最大更新频率之间。例如,如果Actor在两次有意义的更新之间恰好间隔了一秒,那么它会将下一次更新尝试安排在未来0.7秒(或者接近指定的最小与最大更新频率的时间)。对于接下来每次有意义的更新,都将重复该计算,如果Actor开始频繁地进行数据或子对象更改,将快速缩短更新之间的时间。

欢迎帮助改进虚幻引擎文档!请告诉我们该如何更好地为您服务。
填写问卷调查
取消