UObject复制与RPC

UObject复制

一、覆写函数IsSupportedForNetworking 让UObject支持复制

复制代码
virtual bool IsSupportedForNetworking() const override { return true; }

还需要在Actor中重写ReplicateSubobjects让子对象实现复制

复制代码
// 子对象
UCLASS()
class UMagicInventory : public UObject
{
    GENERATED_BODY()

public:
	virtual bool IsSupportedForNetworking() const override { return true; }
	
    UPROPERTY(Replicated)
    TArray<FString> Items;
};

// Actor
UCLASS()
class AMagicBox : public AActor
{
    GENERATED_BODY()

public:
    AMagicBox()
    {
        bReplicates = true; // Actor 开启网络复制
        Inventory = CreateDefaultSubobject<UMagicInventory>(TEXT("Inventory"));
    }

    UPROPERTY()
    UMagicInventory* Inventory;

    virtual bool ReplicateSubobjects(UActorChannel* Channel, FOutBunch* Bunch, FReplicationFlags* RepFlags) override
    {
        bool WroteSomething = Super::ReplicateSubobjects(Channel, Bunch, RepFlags);

        if (Inventory)
        {
            // 将子对象 Inventory 同步到客户端
            WroteSomething |= Channel->ReplicateSubobject(Inventory, *Bunch, *RepFlags);
        }

        return WroteSomething;
    }
};

ReplicateSubobjects实现了将AMagicBox的Inventory变量同步到了客户端

如果 不重写 ReplicateSubobjects:

  • Inventory 指针在客户端是 nullptr
  • UMagicInventory 完全不存在
  • 后面就算 Items 标了 Replicated也毫无意义

同时也要重写IsSupportedForNetworking,如果不返回true,则同样:

  • Inventory 指针在客户端是 nullptr
  • UMagicInventory 完全不存在

还需要注意的是Items的复制是GetLifetimeReplicatedProps处理的 不是ReplicateSubobjects处理的,因此UObject内的变量复制也要写完GetLifetimeReplicatedProps的一整套内容

二、注册子对象列表

是5.7版本的新功能,与ReplicateSubobjects做的事基本相同,但是更简洁,适配Iris复制系统

  • 在 Actor 或 Actor Component 的构造函数中启用:
    bReplicateUsingRegisteredSubObjectList = true;
  • 当你创建或想要复制子对象时,在运行时调用:
    AddReplicatedSubObject(YourSubObject);
  • 当子对象销毁或不再需要复制时,调用:
    RemoveReplicatedSubObject(YourSubObject);

AddReplicatedSubObject可以调用的时机?

"此刻是否已经有 ActorChannel,并且我是在服务器上?"

常用位置:

  • 1.BeginPlay()(服务器端)

    • 最常见
    • 生命周期稳定
    • 网络系统已就绪
  • 2.PostInitializeComponents()(服务器端)

    • 比 BeginPlay 更早
    • 适合组件 / 子对象结构初始化完成后立刻注册
  • 3.任何服务器逻辑函数

    • 例如拾取、生成、绑定能力、打开箱子
    • 只要满足:
      • 对象已存在
      • Actor 已开始复制
  • 4.动态创建子对象之后立刻调用

    复制代码
      Inventory = NewObject<UMagicInventory>(this); 
      AddReplicatedSubObject(Inventory);

注意构造函数,OnRep_函数不能调用AddReplicatedSubObject

三、UObject中使用RPC

覆写以下函数让UObject支持RPC ,注意 UPROPERTY() int TestInt; 类中必须有一个UPROPERTY的属性,否则RPC无法调用!

复制代码
#pragma region UObjectNetworking
public:
	virtual bool IsSupportedForNetworking() const override
	{
		return true;
	}

	virtual int32 GetFunctionCallspace(UFunction* Function, FFrame* Stack)
	{
		int32 Callspace = FunctionCallspace::Local;
		if (UObject* Outer = GetOuter()) Callspace = Outer->GetFunctionCallspace(Function, Stack);
		return Callspace;
	}

	//要有一个UPROPERTY()修饰的变量
	UPROPERTY()
	int TestInt;

	AActor* GetActorOuter() const
	{
		return GetTypedOuter<AActor>();
	}

	virtual bool CallRemoteFunction(UFunction* Function, void* Parms, FOutParmRec* OutParms, FFrame* Stack) override
	{
		AActor* Actor = GetTypedOuter<AActor>();
		if (UNetDriver* NetDriver = Actor->GetNetDriver())
		{
			NetDriver->ProcessRemoteFunction(Actor, Function, Parms, OutParms, Stack, this);
			return true;
		}
		return false;
	}

#pragma endregion 
相关推荐
Rabitebla4 分钟前
C++11 新特性详解(一):列表初始化、initializer_list 与右值引用
java·开发语言·数据结构·c++·算法·leetcode·list
天吾cc6 分钟前
RTT-MQTT
网络·单片机·嵌入式硬件·算法
千视kiloview11 分钟前
“轻”不等于降级:IP时代广播制作系统的轻量化与Hybrid架构实践
网络·tcp/ip·架构
不爱土豆唯爱马铃薯28 分钟前
升级 AiPy Pro 2.0 后,我把安全中心这几项挨个打开了数据安全、沙盒权限、工作空间隔离——这些 2.0 新功能对科研协作场景的实际影响
网络·安全·php
m0_7494922232 分钟前
精密制造检测设备采购:五款超高精度三坐标测量机对比
网络协议
南京码讯光电技术有限公司1 小时前
What Does Ex tb IIIC T80°C Db Mean?
服务器·网络·数据库
MC皮蛋侠客1 小时前
TDengine C++ 系列(11):性能模型与调优——从测量到优化
c++·php·tdengine
小绫网络安全1 小时前
【每日一讲】Pikachu漏洞练习靶场
网络·web安全·网络安全·靶场·pikachu
长江&后浪1 小时前
华为wlan实验-三层旁挂
运维·服务器·网络·华为
兔兔兔兔11 小时前
记录C++ 3
开发语言·c++