查看: 359|回复: 5

[游戏性指南] 【组件复制 | Unreal Engine】

[复制链接]

1

主题

342

帖子

7万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
75866
发表于 2016-6-27 17:00:15 | 显示全部楼层 |阅读模式


本页面的内容:

      
使用方法
C++
蓝图

时间轴

带宽消耗

一般性的子对象复制
使用情形

优化
     
虚幻引擎 4 支持组件复制。尽管使用起来简单直观,但它却有些不同寻常:大多数组件都不会复制。其多数游戏逻辑都是在 Actor 类和组件中完成,而它们通常只代表了构成 Actor 的零散部分。实际复制的是 Actor 中的游戏逻辑,而这样做的结果,有时会调用/更改组件。但在有些情况下,组件本身的属性或事件必须要直接复制。这份指南将介绍如何使用这一功能。

组件会作为其所属 Actor 的一部分进行复制。Actor 仍然掌管角色、优先级、相关性、剔除等方面的工作。一旦复制了 Actor,它就可以复制自身组件。这些组件 可以按 Actor 的方式复制属性和 RPC。组件必须以 Actor 的方式实施 ::GetLifetimeReplicatedProps (...) 函数。

组件复制中涉及两大类组件。一种是随 Actor 一起创建的静态组件。也就是说,在客户端或服务器上生成所属 Actor 时,这些组件也会同时生成,与组件是否被复制无关。服务器不会告知客户端显式生成这些组件。在此背景下,静态组件是作为默认子对象在 C++ 构造函数中创建,或是在蓝图编辑器的组件模式中创建。静态组件无需通过复制存在于客户端;它们将默认存在。只有在属性或事件需要在服务器和客户端之间自动同步时,才需要进行复制。

动态组件是在运行时在服务器上生成的组件种,其创建和删除操作也将被复制到客户端。它们的运行方式与 Actor 极为一致。与静态组件不同, 动态组件需通过复制的方式存在于所有客户端。另外,客户端可以生成自己的本地非复制组件。这适合于很多种情形。只有当那些在服务器上触发的 属性或事件需要自动同步到客户端时,才会出现复制行为。
使用方法
在组件上设置属性和 RPC 的过程与 Actor 并无区别。将一个类设置为具有复本后,这些组件的实际实例也必须经过设置后才能复制。

C++
要进行组件复制,只需调用 AActorComponent::SetIsReplicated(true) 即可。如果您的组件是一个默认子对象,就应当在生成组件之后通过类构造函数来完成此调用。

例:

ACharacter::ACharacter(){    // Etc...    CharacterMovement = CreateDefaultSubobjectUMovementComp_Character(TEXT("CharMoveComp"));    if (CharacterMovement)    {
CharacterMovement-UpdatedComponent = CapsuleComponent;
CharacterMovement-GetNavAgentProperties()-bCanJump = true;
CharacterMovement-GetNavAgentProperties()-bCanWalk = true;
CharacterMovement-SetJumpAllowed(true);
CharacterMovement-SetNetAddressable(); // Make DSO components net addressable
CharacterMovement-SetIsReplicated(true); // Enable replication by default    }}
蓝图
要进行静态蓝图组件复制,只需在组件默认设置中切换 Replicates 布尔变量。同样,只有当组件中拥有需要复制的属性或事件时,才需要 进行此操作。静态组件需要在客户端和服务器上隐式创建。

【虚幻4翻译文档-组件复制 | Unreal Engine】[虚幻4中文文档]



需要注意的是,并非所有组件都会如此显示,必须要支持某种复制形式才会显示。

要通过动态生成的组件来实现这一点,可以调用 SetIsReplicated 函数:

【虚幻4翻译文档-组件复制 | Unreal Engine】[虚幻4中文文档]


时间轴
时间轴必须通过其属性中的 Replicated 选项来启用复制。这会将服务器控制的运行位置、速率和方向复制到客户端。这是一种基本的实施,可以根据需求的变化而进行演变。大多数时间轴都无需复制。和所有游戏对象复本一样,时间轴复本只应当在服务器上直接操作 (start/stop etc)。客户端只应当查看运行位置的复本,而不应尝试改变时间轴本身。在进行复制更新的间歇,客户端将推测运行位置。
带宽消耗
复制组件时的资源消耗量是比较低的。要复制的 Actor 中的每个组件都需要添加一个额外的 NetGUID(4 字节)“标头”和一个大约 1 字节的“标脚”(footer) 及其属性。在 CPU 层面上,基于 Actor 的属性复制与基于组件的复制之间应当有一个最小差异。
一般性的子对象复制
对这个问题,我们可以更进一步:所有 Actor 子对象都可以复制,而不只限于组件。

这个结论的应用范围很窄,但在某些情形下却非常实用。实现这一目的所用的接口需要在类的层面上定义:

/** FActory 方法,用于对模板化 TobjectReplicator 类进行实例化,以便实现子对象复制 */virtual class FObjectReplicatorBase * InstantiateReplicatorForSubObject(UClass *SubobjClass);/** 能让 Actor 在其 Actor 通道上复制子对象的方法 */virtual bool ReplicateSubobjects(class UActorChannel *Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags);/** 通过复制来动态创建新的子对象时,在 Actor 上进行调用 */virtual void OnSubobjectCreatedFromReplication(UObject *NewSubobject);
对于希望复制非 ActorComponent 子对象的类,应当实施以上三种方法。

使用情形
这是一种很有用的手段,因为它能在 Actor 通道的层面上使用 UObject 和多态(polymorphism)。之前用于复杂数据结构的复制方法只适合那些 在 Actor 类中对类型进行静态定义的结构。利用子对象复制,您可以享受诸多优势,例如建立一个道具栏系统,使其中的每个物品作为一个从基本道具栏类扩展而来的类, 也可以进行完整复制,同时无需让这些项成为 Actor(资源负担太大)。
优化
如果有很多子对象需要复制,Actor 只需了解哪些子对象(如存在)最近发生过变化且需要复制,从而节省了大量时间。这需要通过访问器(accessor)函数来持续跟踪子对象的更改情况。这一过程所用的接口位于 AActorChannel 中:

bool KeyNeedsToReplicate(int32 ObjID, int32 RepKey);
该函数应当由 Actor 在其 ::ReplicateSubobjects 实施中调用。Actor 类可以设置一个任意的对象 ID 和复制键,供复制系统跟踪每个客户端。当 ReplicateSubobjects 返回 true 时,调用方应当在使用该对象 ID 接受跟踪的任意子对象上调用 ReplicateSubobjects。相关示例请查看 AQAInventory::ReplicateSubobjects。一定不要忘记,对象 ID 和复制键完全是任意指定的。对象 ID 仅用于引用“事情”。它可以是整个子对象列表、部分列表或单个对象。复制键同样可以任意指定 - 它可以是一个在对象 ID 跟踪变化时递增的计数器。这里讨论的优化问题完全是选读内容。



   



   



      




   


      相关页面

  




       Actor 的复制








      属性复制








      性能与带宽提示




回复

使用道具 举报

0

主题

865

帖子

2854

积分

vip会员

Rank: 1

积分
2854
发表于 2016-7-2 20:26:01 | 显示全部楼层
大水比一个,路过支持一下
回复 支持 反对

使用道具 举报

0

主题

1414

帖子

4080

积分

vip会员

Rank: 1

积分
4080
发表于 2016-7-4 02:59:59 来自手机 | 显示全部楼层
恩,好资源~ 哈哈~
回复 支持 反对

使用道具 举报

0

主题

882

帖子

2914

积分

vip会员

Rank: 1

积分
2914
发表于 2016-7-4 12:45:36 | 显示全部楼层
我来看看 这个怎么样
回复 支持 反对

使用道具 举报

0

主题

856

帖子

2821

积分

vip会员

Rank: 1

积分
2821
发表于 2016-7-11 21:45:23 来自手机 | 显示全部楼层
加油摸摸大,感谢楼主分享
回复 支持 反对

使用道具 举报

0

主题

877

帖子

2880

积分

vip会员

Rank: 1

积分
2880
发表于 2016-7-26 19:55:57 来自手机 | 显示全部楼层
不错,我喜欢这个,看看多少金币哦
回复 支持 反对

使用道具 举报

*滑块验证:
您需要登录后才可以回帖 登录 | enginedx注册

本版积分规则

 
 



邮件留言:


 
返回顶部