Properties that uses DOREPLIFETIME_ACTIVE_OVERRIDE (ex. RepRootMotion ) will also skip replication when an actor channel is newly opened.
This means that if the variables on the server side do not change, the opportunity to synchronize the property will be lost forever.
ACharacter::RepRootMotion.IsActive on a client will be fixed to a false value due to this behavior, and it disables root motion movement synchronization.


The following workarounds works. It will check the properties when the actor channel is newly opened regardless of the DOREPLIFETIME_ACTIVE_OVERRIDE flag.

// Compare the specific FRepParentCmd.
// Returns true if the property (or any of its nested FRepLayoutCmds) has changed.
static bool CompareParentProperty(
	const int32 ParentIndex,
	const FComparePropertiesSharedParams& SharedParams,
	FComparePropertiesStackParams& StackParams)
		const FRepParentCmd& Parent = SharedParams.Parents[ParentIndex];
		const bool bIsLifetime = EnumHasAnyFlags(Parent.Flags, ERepParentFlags::IsLifetime);

		// Active state of a property applies to *all* connections.
		// If the property is inactive, we can skip comparing it because we know it won't be sent.
		// Further, this will keep the last active state of the property in the shadow buffer,
		// meaning the next time the property becomes active it will be sent to all connections.
#if 1 // workaround
		const bool bIsActive = !SharedParams.RepChangedPropertyTracker || SharedParams.RepChangedPropertyTracker->Parents[ParentIndex].Active || SharedParams.bIsInitial;
		const bool bIsActive = !SharedParams.RepChangedPropertyTracker || SharedParams.RepChangedPropertyTracker->Parents[ParentIndex].Active;
		const bool bShouldSkip = !bIsLifetime || !bIsActive || (Parent.Condition == COND_InitialOnly && !SharedParams.bIsInitial);



Steps to Reproduce
  1. build attached [Link Removed]and launch editor
  2. Set "Number of Players" 3 and start PIE 
  3. Focus a client view
  4. Press keyboard Z to play montage (Now RepRootMotion.IsActive on another client is set to 1 )
  5. Move actor to further to close the actor channel (NetCullDistance is set to 600*600)
  6. Move near the other client and reopen the actor channel.
  7. Press Z on the keyboard to move the actor and look at the log.
    You will see that RepRootMotion.IsActive is still set to 0.
  8. Pressing C key will spawn a wall in front of the actor only on the server, and the actor will walk towards the wall
  9. You can see that movement synchronization during root motion did not work in another client viewport


[Link Removed]




Have Comments or More Details?

There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-119442 in the post.

Login to Vote

ComponentUE - Networking
Affects Versions4.25
CreatedJul 12, 2021
UpdatedJan 28, 2022