【UE 网络】Actor复制究竟同步了哪些信息?

请添加图片描述

  • 🙋‍♂️ 作者:海码007
  • 📜 专栏:UE虚幻引擎专栏
  • 💥 标题:【UE 网络】Actor复制究竟同步了哪些信息?
  • ❣️ 寄语:书到用时方恨少,事非经过不知难!
  • 🎈 最后:文章作者技术和水平有限,如果文中出现错误,希望大家能指正,同时有问题的话,欢迎大家留言讨论。

0 引言

在开发过程中,我以为将Actor标记为可复制之后,有关这个Actor的所有属性都会进行一个同步。但其实只会同步一部分信息。

参考文章:Actor第一次被创建时经历了什么
官方参考文章:Actor复制流程详述

1 会同步的信息

1.1 对象的生命周期

Actor的生成和销毁会被自动同步,因为这些操作是通过Unreal Engine的网络复制系统处理的。服务器会将生成和销毁指令发送给所有客户端,以确保游戏状态的一致性。通过将Actor标记为可复制(bReplicates = true)

2 需要手动设置同步的信息

2.1 对象的基本属性(Location、Rotation、Scale)

Actor的移动状态同步需要设置 bReplicateMovement 变量为 true 时,才会网络同步给客户端。

C++属性:
在这里插入图片描述

蓝图属性:
在这里插入图片描述

在Actor内部是通过bReplicateMovement 变量和 FRepMovement 结构体配合实现控制 Actor 的运动状态的同步。以下是它们如何协同工作的总结:

2.1.1 bReplicateMovement 变量

  • 作用bReplicateMovementAActor 类的一个布尔变量,用于控制是否自动复制 Actor 的运动状态。
  • 设置:当 bReplicateMovement 被设置为 true 时,Unreal Engine 会自动处理该 Actor 的运动状态的复制。
  • 自动化:启用 bReplicateMovement 后,开发者无需手动编写复杂的复制逻辑,Unreal Engine 会自动同步位置、旋转、线性速度和角速度。

2.1.2 FRepMovement 结构体

  • 作用FRepMovement 是一个结构体,包含了与 Actor 运动相关的多个属性,例如位置、旋转、线性速度和角速度。
  • 存储和传输:当 bReplicateMovement 被启用时,Unreal Engine 内部会使用 FRepMovement 结构体来存储和传输运动状态。
  • 回调函数:可以使用 ReplicatedUsing 属性和回调函数(如 OnRep_ReplicatedMovement)来处理复制更新后的逻辑。

2.1.3 配合工作流程

  1. 启用复制

    • 在 Actor 的构造函数中,将 bReplicates 设置为 true,以启用网络复制。
    • bReplicateMovement 设置为 true,以启用运动状态的自动复制。
  2. 自动处理

    • bReplicateMovement 被设置为 true 时,Unreal Engine 会自动使用 FRepMovement 结构体来存储和传输运动状态。
    • 服务器会将 FRepMovement 结构体中的数据(位置、旋转、线性速度和角速度)复制到客户端。
  3. 回调函数

    • 可以使用 ReplicatedUsing 属性和回调函数(如 OnRep_ReplicatedMovement)来处理复制更新后的逻辑。例如,当 FRepMovement 结构体中的数据在客户端被更新时,回调函数会被调用,以便开发者可以在客户端上执行额外的逻辑。

以下是一个简化的示例,展示了如何使用 bReplicateMovementFRepMovement 来自动同步 Actor 的运动状态:

// MyActor.h
UCLASS()
class MYGAME_API AMyActor : public AActor
{
    GENERATED_BODY()

public:
    AMyActor();

protected:
    virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;

    UPROPERTY(EditDefaultsOnly, ReplicatedUsing=OnRep_ReplicatedMovement, Category=Replication, AdvancedDisplay)
    FRepMovement ReplicatedMovement;

    UFUNCTION()
    void OnRep_ReplicatedMovement();
};

// MyActor.cpp
AMyActor::AMyActor()
{
    bReplicates = true; // 启用Actor的网络复制
    bReplicateMovement = true; // 启用运动状态的自动复制
}

void AMyActor::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
    Super::GetLifetimeReplicatedProps(OutLifetimeProps);

    DOREPLIFETIME(AMyActor, ReplicatedMovement);
}

void AMyActor::OnRep_ReplicatedMovement()
{
    // 处理位置和速度的更新逻辑
    if (RootComponent)
    {
        RootComponent->SetWorldLocationAndRotation(ReplicatedMovement.Location, ReplicatedMovement.Rotation);
        // 其他更新逻辑,例如速度
    }
}

2.1.4 UE4的特性

在 DS 上创建 一个Actor 后(可复制),然后重新设置Actor位置,发现客户端和服务器的位置都同步了,但是此时我并没有开启 bReplicateMovement 属性。然后在服务器 Tick 里面持续修改 Actor位置后发现客户端此时没有再同步。 (就是在服务器上创建一个可复制的 Actor 时,初始位置会自动同步到客户端。)

如果开启 bReplicateMovement 属性,服务器Tick里面修改Actor位置,客户端会持续同步位置。

总结:首次复制时会带上当前的 Location,这是在客户端打开通道(Open Channel)时写入的。在客户端打开通道之前对 Location 的修改会被包含在初始同步数据中,并在通道打开时发送给客户端。打开通道之后的修改则需要依赖于 bReplicateMovement 属性来决定是否同步。

2.2 组件的同步

如果我们在Actor中添加了某些组件,组件是否能网络同步,需要在组件内部设置,它并不会继承Actor同步的设置。

蓝图设置位置如下:
在这里插入图片描述

2.3 成员变量和方法

在类中声明的变量和方法如果需要进行网络同步,也需要再进行额外的设置才行。(使用UPROPERTY宏和元数据进行表示变量可复制)

2.4 Tags标签

在我的游戏开发过程中,我得知,Tags标签也是需要进行手动的同步设置的。只将Actor标记为可复制,并不会同步Tags信息 。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值