Unreal Engine 高效数组复制用法详解

文章目录


前言

在 Unreal Engine 中,FFastArraySerializerFFastArraySerializerItem 是用于高效网络复制数组数据的工具类,尤其在需要频繁同步动态数组时(如背包系统、技能列表等场景)。以下通过一个 背包物品同步 的示例详细说明它们的用法。


提示:以下是本篇文章正文内容,下面案例可供参考

一、核心概念

  • FFastArraySerializerItem: 表示数组中的单个元素,需要包含复制标识符 ReplicationID 和 ReplicationKey。
  • FFastArraySerializer: 管理数组的容器类,负责处理网络复制逻辑和变化追踪。

二、实现步骤

2.1 定义 Item 结构体

cpp 复制代码
// 继承自 FFastArraySerializerItem
USTRUCT()
struct FInventoryItem : public FFastArraySerializerItem
{
    GENERATED_BODY()

    UPROPERTY()
    FName ItemID;       // 物品唯一ID

    UPROPERTY()
    int32 Quantity;     // 数量

    UPROPERTY()
    float Durability;   // 耐久度

    // 网络复制标识符(必须实现)
    void PreReplicatedRemove(const struct FInventoryArray& Serializer);
    void PostReplicatedAdd(const struct FInventoryArray& Serializer);
    void PostReplicatedChange(const struct FInventoryArray& Serializer);
};

2.2 定义数组容器

cpp 复制代码
// 继承自 FFastArraySerializer
USTRUCT()
struct FInventoryArray : public FFastArraySerializer
{
    GENERATED_BODY()

    UPROPERTY()
    TArray<FInventoryItem> Items;  // 物品数组

    // 必须重写:标识数组变化
    bool NetDeltaSerialize(FNetDeltaSerializeInfo& DeltaParms) override
    {
        return FFastArraySerializer::FastArrayDeltaSerialize<FInventoryItem, FInventoryArray>(Items, DeltaParms, *this);
    }

    // 示例方法:添加物品
    void AddItem(const FInventoryItem& NewItem)
    {
        Items.Add(NewItem);
        MarkItemDirty(Items.Last()); // 标记为脏数据以触发复制
    }

    // 示例方法:移除物品
    void RemoveItem(int32 Index)
    {
        if (Items.IsValidIndex(Index))
        {
            Items.RemoveAt(Index);
            MarkArrayDirty(); // 标记数组变化
        }
    }
};

2.3 在 Actor 或 Component 中使用

cpp 复制代码
UCLASS()
class AMyCharacter : public ACharacter
{
    GENERATED_BODY()

public:
    // 复制的背包数据
    UPROPERTY(Replicated)
    FInventoryArray Inventory;

    // 注册复制属性
    virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override
    {
        Super::GetLifetimeReplicatedProps(OutLifetimeProps);
        DOREPLIFETIME(AMyCharacter, Inventory);
    }

    // 服务器端添加物品
    UFUNCTION(Server, Reliable)
    void Server_AddItem(FName ItemID, int32 Quantity);
    {
        FInventoryItem NewItem;
        NewItem.ItemID = ItemID;
        NewItem.Quantity = Quantity;
        NewItem.Durability = 100.f;
        Inventory.AddItem(NewItem);
    }
};

三、关键方法说明

3.1 MarkItemDirty()

  • 作用: 标记单个 Item 为"脏数据",触发网络复制。

  • 使用场景: 修改 Item 属性后调用,如:

cpp 复制代码
void ChangeItemQuantity(int32 Index, int32 NewQuantity)
{
    if (Inventory.Items.IsValidIndex(Index))
    {
        Inventory.Items[Index].Quantity = NewQuantity;
        Inventory.MarkItemDirty(Inventory.Items[Index]);
    }
}

3.2 MarkArrayDirty()

  • 作用: 标记整个数组变化(如添加/删除元素)。

  • 自动调用: 通过 AddItem() 或 RemoveItem() 间接调用。

四、回调函数处理

FInventoryItem 中实现复制回调,响应数据变化:

cpp 复制代码
void FInventoryItem::PostReplicatedAdd(const FInventoryArray& Serializer)
{
    // 客户端新增物品时触发(如更新UI)
    UMyUIWidget::Get()->RefreshInventory();
}

void FInventoryItem::PostReplicatedChange(const FInventoryArray& Serializer)
{
    // 客户端物品属性变化时触发(如更新数量显示)
    UMyUIWidget::Get()->UpdateItemDisplay(ItemID);
}

void FInventoryItem::PreReplicatedRemove(const FInventoryArray& Serializer)
{
    // 客户端移除物品前触发(如播放消失动画)
    UMyUIWidget::Get()->RemoveItemDisplay(ItemID);
}

五、网络复制流程

  1. 服务器修改数据 :调用 AddItem()RemoveItem() 或直接修改 Item 属性后标记脏数据。

  2. 引擎自动同步 :通过 NetDeltaSerialize 增量复制变化到客户端。

  3. 客户端触发回调 :根据操作类型(Add/Change/Remove)执行 PostReplicatedAdd 等函数。

六、注意事项

  • 仅在服务器修改数据 :客户端应通过 RPC(如 Server_AddItem)请求修改。

  • 避免频繁操作 :批量操作后调用一次 MarkArrayDirty() 减少带宽。

  • 自定义序列化 :如需优化,可重写 FInventoryItem::NetSerialize()

通过这种机制,FFastArraySerializer 能高效同步动态数组,适用于需要低延迟和高频率更新的游戏系统。

相关推荐
闪电麦坤955 小时前
Unity:Simple Follow Camera(简单相机跟随)
unity·游戏引擎
帮帮志7 小时前
05.unity 游戏开发-3D工程的创建及使用方式和区别
3d·unity·游戏引擎
闪电麦坤958 小时前
Unity:标签(tags)
unity·游戏引擎
妙为14 小时前
ue5 仿鬼泣5魂类游戏角色和敌人没有碰撞
游戏·ue5·碰撞
虾球xz16 小时前
游戏引擎学习第206天
c++·学习·游戏引擎
闪电麦坤9518 小时前
Unity:销毁(Destroy)
unity·游戏引擎
一线灵19 小时前
跨平台游戏引擎 axmol-2.5.0 发布
c++·游戏引擎·wasm·axmol
虾球xz19 小时前
游戏引擎学习第201天
前端·学习·游戏引擎
ue星空1 天前
Blender模型导入虚幻引擎设置
游戏引擎·blender·虚幻