UE本身有一套自创的网络框架,
在这个框架里UObject类型默认是无法进行属性同步的.
如果想要UObject进行属性同步就必须进行一系列重写.
示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| UCLASS(BlueprintType, Blueprintable) class UMyTestObject : public UObject { GENERATED_BODY() public: UMyTestObject(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());
public: virtual UWorld* GetWorld() const override;
virtual bool IsSupportedForNetworking() const override; virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
int32 GetFunctionCallspace(UFunction* Function, FFrame* Stack); bool CallRemoteFunction(UFunction* Function, void* Parameters, struct FOutParmRec* OutParams, FFrame* Stack);
public: UPROPERTY(Replicated) uint32 bReplicatedFlag : 1; };
UMyTestObject::UMyTestObject(const FObjectInitializer& ObjectInitializer ) :UObject(ObjectInitializer) {
}
UWorld* UMyTestObject::GetWorld() const { if (const UObject* MyOuter = GetOuter()) { return MyOuter->GetWorld(); } return nullptr; }
bool UMyTestObject::IsSupportedForNetworking() const { return true; }
void UMyTestObject::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const { Super::GetLifetimeReplicatedProps(OutLifetimeProps); DOREPLIFETIME(UMyTestObject, bReplicatedFlag); }
bool UMyTestObject::CallRemoteFunction(UFunction* Function, void* Parameters, struct FOutParmRec* OutParams, FFrame* Stack) { if (AActor* OuterActor = Cast<AActor>(GetOuter())) { UNetDriver* NetDriver = OuterActor->GetNetDriver(); if (NetDriver) { NetDriver->ProcessRemoteFunction(OuterActor, Function, Parameters, OutParams, Stack, this); return true; } } return false; }
int32 UMyTestObject::GetFunctionCallspace(UFunction* Function, FFrame* Stack) { if (AActor* OuterActor = Cast<AActor>(GetOuter())) { return OuterActor->GetFunctionCallspace(Function, Stack); }
return FunctionCallspace::Local; }
|
在BasePlayerController.h中添加:

由于Replicated, 需要将pTestObj添加到GetLifetimeReplicatedProps中.

重写ABasePlayerController::ReplicateSubobjects函数,
将pTestObj添加到ABasePlayerController列表中.

在BasePlayerController.cpp中动态创建:

经过上述步骤, 可以将自定义UMyTestObject进行属性同步.
UE Replicate流程
UE在进行属性同步时候, 首先进行Actor自身的属性同步, 然后同步SubObject,
最后才同步自定义UObject.
1 2 3 4 5 6 7 8 9 10 11 12 13
| --UNetDriver.TickFlush() |--UNetDriver.ServerReplicateActors() | |--UNetDriver.ServerReplicateActors_ProcessPrioritizedActors() | | |--UActorChannel.ReplicateActor() | | | |-- | | | |--FObjectReplicator.ReplicateProperties() | | | |--AActor.ReplicateSubobjects() | | | | |-- | | | | |--UActorComponent.ReplicateSubobjects() | | | | |--UActorChannel.ReplicateSubobject() | | | | |-- | | | | |--UActorChannel.ReplicateSubobject()
|
引用:RPC浅析