属性复制

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

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开始频繁地进行数据或子对象更改,将快速缩短更新之间的时间。

Select Skin
Light
Dark

Welcome to the new Unreal Engine 4 Documentation site!

We're working on lots of new features including a feedback system so you can tell us how we are doing. It's not quite ready for use in the wild yet, so head over to the Documentation Feedback forum to tell us about this page or call out any issues you are encountering in the meantime.

We'll be sure to let you know when the new system is up and running.

Post Feedback