Hello!
I was able to fix the issue using based movement and a custom movement mode.
You should know that both the server and the client use the relative transform of BasedMovement.MovementBase
for character replication. If MovementBase
is NULL
, the absolute transform is used instead.
MovementBase
is set automatically by movement modes like the walking mode when the character lands on the ground, or cleared (set to NULL
) when the character is falling.
So I created a new custom movement mode to set the base component when the player is attached, using an override of UTagCharacterMovementComponent::PhysCustom
:
void UTagCharacterMovementComponent::PhysCustom(float deltaTime, int32 Iterations)
{
if (CustomMovementMode == CUSTOM_MOVEMENT_MODE_STUCKTOZONE)
{
PhysStuckToZone(deltaTime, Iterations);
}
Super::PhysCustom(deltaTime, Iterations);
}
void UTagCharacterMovementComponent::PhysStuckToZone(float deltaTime, int32 Iterations)
{
// Code with SetBase()
}
Now, the client will replicate the character’s position based on the attached component instead of the world transform. The tricky part is that based movement is generally used without attachment.
-
Without attachment: if my base component moves 50, the character also moves 50 cm.
-
With attachment: if the base moves 50 cm, the character moves 50 cm from the attachment plus another 50 cm from the movement base logic so it moves 100 cm in total.
But thanks it possible to simply cancel based movement updates during this mode by overriding UTagCharacterMovementComponent::UpdateBasedMovement
:
void UTagCharacterMovementComponent::UpdateBasedMovement(float DeltaSeconds)
{
if (MovementMode == MOVE_Custom && CustomMovementMode == CUSTOM_MOVEMENT_MODE_STUCKTOZONE)
{
// Disable base movement update when using the stuck zone
return;
}
Super::UpdateBasedMovement(DeltaSeconds);
}
I’m not sure if it’s the best solution, but it’s definitely much cleaner than recalculate and forcing the client’s position in UCharacterMovementComponent::OnMovementUpdated
.
Hope this helps someone else!