GetLifetimeReplicatedProps calls only once on subobject

I used the subobject replication on Character child class.
The replication code in subobject:

void UIndicatorsComponent::GetLifetimeReplicatedProps(TArray< FLifetimeProperty > & OutLifetimeProps) const
{
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);
	DOREPLIFETIME(UIndicatorsComponent, Health);
}

But this code runs only once. Consequently Health property is not replicated when it changes.

Code in class that replicates this subobject:

bool ASADCharacter::ReplicateSubobjects(class UActorChannel *Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags)
{
	bool WroteSomething = Super::ReplicateSubobjects(Channel, Bunch, RepFlags);
	
	if (Indicators != nullptr)
	{
		WroteSomething |= Channel->ReplicateSubobject(Indicators, *Bunch, *RepFlags);
	}

	return WroteSomething;
}

Subobject has this :

UPROPERTY(Replicated)
float Health;

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

That’s not a bug. You are misunderstanding how it works.

Unreal will automatically replicate any UPROPERTY declared properties by declaring that they are Replicated and implementing UObject::GetLifetimeReplicatedProps(). Warning: It is vitally important that you do not conditionally replicate values inside GetLifetimeReplicatedProps (i.e. do not use any of your objects instance state to conditionally wrap DOREPLIFETIME). Doing this will not do what you think (internally Unreal only ever calls GetLifetimeReplicatedProps() on the first instance of an object of a given class and it expects to be given the replication layout for that class, not for an instance of that class. That replication layout is shared by all instances of that class for the lifetime of the UNetDriver).

You can read more here:

https://wiki.unrealengine.com/Replication

Whatever problem you are having is caused by something else. Most likely, your subobject is not replicated its own properties correctly. If you post the code, I can take a look at it.

Subobject Paste.ee Paste.ee

Object used this subobject: Paste.ee Paste.ee

Thanks for help!

You’re attempting to manually replicate a subclass of UActorComponent. It will misbehave. You have two choices:

A. Derive from UObject for your subobject and replicate manually (implementing IsSupportedForNetworking on the subobject, implementing ReplicateSubobjects on the Actor, etc. as you’ve mostly done, but see notes below)

B. Derive from UActorComponent for your subobject. Then simply set it as bReplicates, and make sure you’ve registered the component (which adds it to the Components list for your Actor). UE4 will handle all other stuff for replication.

Note: for replication for work properly on your UObject-derive subobject, you also need to implement GetWorld, GetFunctionCallspace, and CallRemoteFunction.

There are also a couple of other mistakes in your code. You’ve implemented ReplicateSubobjects on your UIndicatorsComponent, but assuming you were replicating it manually, it would never be called. Your outer ASADCharacter must call it from within its own ReplicateSubobjects.

One more additional note: if you’re able to create your UIndicatorsComponent using CreateDefaultSubobject in your initializer, that would be good. Then your component will have a stable name relative to its outer, which means the server and client will have to exchange less data (the client will not have to receive instructions to create the subobject from the server). If the subobject is removed, the server will still correctly tell the client to remove it.

Okay! Thanks a lot!