NT-2.3.1|UObject复制同步和RPC
大约 2 分钟
本章概要
非Actor对象,比如原生的UObject如何实现同步?以及调用RPC
问题
变量同步
1. 重写 IsSupportedForNetworking
在自定义 UObject
类中重写 IsSupportedForNetworking
函数,使其返回 true
,标记该对象支持网络复制。
UCLASS()
class YOURGAME_API UInventoryPickUpData : public UObject
{
GENERATED_BODY()
public:
virtual bool IsSupportedForNetworking() const override
{
return true;
}
UPROPERTY(Replicated)
int32 ItemID;
// 添加其他需要复制的属性
};
2. 标记属性为 Replicated
确保复制的属性被标记为 UPROPERTY(Replicated)
或者使用 ReplicateUsing
。
3. 实现复制支持
在拥有 UObject
子对象的类中,使用 GetLifetimeReplicatedProps
函数实现复制支持:
void AYourActor::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
// 添加需要复制的子对象
DOREPLIFETIME(AYourActor, InventoryItem);
}
4. 调用 ReplicateSubobject
确保在 AActor
的 GetSubobjectsWithStableNamesForNetworking
或 ReplicateSubobjects
函数中调用 ReplicateSubobject
:
bool AYourActor::ReplicateSubobjects(class UActorChannel* Channel, class FOutBunch* Bunch, FReplicationFlags* RepFlags)
{
bool WroteSomething = Super::ReplicateSubobjects(Channel, Bunch, RepFlags);
if (InventoryItem)
{
WroteSomething |= Channel->ReplicateSubobject(InventoryItem, *Bunch, *RepFlags);
}
return WroteSomething;
}
5. 初始化并确保对象正确创建
在构造函数或其他初始化函数中创建和初始化子对象:
AYourActor::AYourActor()
{
bReplicates = true;
InventoryItem = CreateDefaultSubobject<UInventoryPickUpData>(TEXT("InventoryItem"));
}
RPC
1.确保属性变量拥有UPROPERTY(Replicated),UFUNCTION()等反射标记
2. 重写接口(虚函数)
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
virtual int32 GetFunctionCallspace(UFunction* Function, FFrame* Stack) override;
int32 UInventoryPickUpData::GetFunctionCallspace(UFunction* Function, FFrame* Stack)
{
if (AActor* OuterActor = Cast<AActor>(GetOuter()))
{
return OuterActor->GetFunctionCallspace(Function, Stack);
}
return FunctionCallspace::Local;
}
bool UInventoryPickUpData::CallRemoteFunction(UFunction* Function, void* Parms, FOutParmRec* OutParms, FFrame* Stack)
{
if (AActor* OuterActor = Cast<AActor>(GetOuter()))
{
UNetDriver* NetDriver = OuterActor->GetNetDriver();
if (NetDriver)
{
NetDriver->ProcessRemoteFunction(OuterActor, Function, Parms, OutParms, Stack, this);
return true;
}
}
return false;
}
- 正常RPC函数
UFUNCTION(BlueprintCallable,Server,Reliable)
void SpawnPickUpActor(const FTransform& SpawnTransform);
UFUNCTION(BlueprintCallable,Client,Reliable)
void ClientSpawnPickUpActor(const FTransform& SpawnTransform);