Replication of properties in a component

My goal is to replicate hp current value in the following setup:

a UActorComponent named UResourceComponent that contains, among other fields, the following:

UPROPERTY(EditAnywhere,Replicated, BlueprintReadWrite, Category = "Details")
float CurrentValue=100.f;

and by using a tutorial, the following code for replication:

in the header:

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

virtual bool IsSupportedForNetworking() const override
{
	return true;
}

and the cpp:

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

	DOREPLIFETIME(UResourceComponent, CurrentValue);
}

next up, is another UActorComponent named UVitalsComponent
this component holds 3 UResourceComponent as resource bars. for now i am trying to replicate only the hp bar

the header:

UPROPERTY(EditAnywhere,Replicated, BlueprintReadWrite, Category = "Initialization", meta = (EditCondition = bUseResourceHP))
	UResourceComponent* BarHP;	

virtual bool ReplicateSubobjects(class UActorChannel *Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) override;


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

virtual bool IsSupportedForNetworking() const override
{
	return true;
}

and again, following a tutorial, the cpp:
setting BarHP->SetIsReplicated(true); in the constructor

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

	if (BarHP != nullptr)
	{
		WroteSomething |= Channel->ReplicateSubobject(BarHP, *Bunch, *RepFlags);
	}

	return WroteSomething;
}
void UVitalsComponent::GetLifetimeReplicatedProps(TArray< FLifetimeProperty > & OutLifetimeProps) const
{
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);

	DOREPLIFETIME(UVitalsComponent, BarHP);
}

lastly, a character class named Acpp_BaseGameCharacter.
in blueprint i create a class derived from VitalsComponent and add it to the character. after failed tests i decided to search and save the component in the BeginPlay method.

Header:

virtual bool ReplicateSubobjects(class UActorChannel *Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) override;

virtual void GetLifetimeReplicatedProps(TArray< FLifetimeProperty > & OutLifetimeProps) const override;
 
 UPROPERTY(VisibleAnywhere,Replicated)
class UVitalsComponent* vitalsComponent;

and the cpp:

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

	DOREPLIFETIME(Acpp_BaseGameCharacter, vitalsComponent);
}

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

	if (vitalsComponent != nullptr)
	{
		WroteSomething |= Channel->ReplicateSubobject(vitalsComponent, *Bunch, *RepFlags);
	}

	return WroteSomething;
}


void Acpp_BaseGameCharacter::BeginPlay()
{
	Super::BeginPlay();
	vitalsComponent = FindComponentByClass<UVitalsComponent>();
	vitalsComponent->SetIsReplicated(true);
}

i expect that whenever i change the value of current hp on the server, the clients will get updated. it doesnt work and i feel really stupid and sure that i missed something.

Hello.

I’d start with moving following line to the constructor of your Acpp_BaseGameCharacter. I’m guessing it might be way to late (world initialization wise) to set that in BeginPlay.

vitalsComponent->SetIsReplicated(true);

Edit:

Also, make sure your component contructor contains this:

bReplicates = true;

If that doesn’t fix it, I’d remove your ReplicateSubobjects implementation. To be honest i never had to use that to properly replicate component properties. Maybe it’s messing up default replication somehow.

thank you for the reply
vitalsComponent is created in the blueprint, hence im not sure if it will be found at the construct time.
moreover, in the blueprint i also set the replication flag to true.
i added ReplicateSubobjects method only after i tried to make it work without it.

Ah, I see. Then yeah, you won’t find it in contructor. :confused:

I’ve edited my answer (added part about bReplicates property). You might be missing this.

You could also try to do it in AActor::PostInitializeComponents. It’s called somewhere during blueprint compilation/creation/opening. Add some log to make sure so you’ll know when it executes.

thank you i will try the AActor::PostInitializeComponents.
as for breplicates - yeah, same same :stuck_out_tongue: