Characters jitter when moving into each other on a moving base

While on the same moving base, characters constantly jitter if they move into other characters. They also jitter if they stand right behind another character in relation to the moving base’s direction of travel.

The issue stems from resolving false penetrations (for example during floor checks), where CharacterA wrongfully thinks they are inside CharacterB’s capsule. The reason for this false penetration is that CharacterA gets CharacterB’s capsule before its transform is updated with the moving base. Since based movement is updated per-character in each respective CharacterMovementComponent’s tick, this issue has a 100% reproduction rate, as each character cannot guarantee that every other character has already updated their base movement.

I was able to hack fix this by force updating the based movement for all passenger characters after a moving base moves. This ensures that when a character performs their regular movement, they’ll have the most up-to-date transforms from any other character on the same moving base. I do this hack at the end of the moving base’s tick. See code snippet from attached sample project below.

Is there a better way to solve this issue either with or without engine modifications?

void UPlatformMovementComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

	if (bImmediatelyUpdatePassengersOnMove)
	{
		// Force all passengers to update their based movement so that when they apply their input movement, all potentially colliding
		// character capsules are updated to the correct spots.
		if (APlatformPawn* Platform = Cast<APlatformPawn>(GetOwner()))
		{
			const TArray<ACharacter*> Passengers = Platform->GetPassengers();
			for (const ACharacter* Passenger : Passengers)
			{
				if (UPlayerMovementComponent* MovementComponent = Passenger->GetCharacterMovement<UPlayerMovementComponent>())
				{
					MovementComponent->MaybeUpdateBasedMovement(DeltaTime);
					MovementComponent->MaybeSaveBaseLocation();
				}
			}
		}
	}
}

Steps to Reproduce
Steps to Reproduce:

  1. Unzip and open the attached BasedMovementTest.zip (Unreal Engine 5.6.1)
  2. Open Lvl_ThirdPerson
  3. Set PIE Net Mode to “Play as Client” and Number of Players to “2”
  4. Press play
  5. Walk one player into the other (or just have them stand right behind the other in relation to direction of platform travel)
  6. Observe the jitter
  7. Now move both players into the green zone and walk one player into the other
  8. Observe the jitter is gone

Sample Project Setup:

  • Created from third person template
  • Multiplayer, Play as Client, at least 2 clients used
  • BP_ThirdPersonCharacter uses custom UPlayerMovementComponent that sets bBaseOnAttachmentRoot, bStayBasedInAir, and bFastAttachedMove to true
  • BP_MovingPlatform derives from custom APlatformPawn
    • Adds movement input every tick
    • Uses custom UPlatformMovementComponent that derives from UFloatingPawnMovement
      • On tick, this will update passengers’ based movement (if anyone stands in the green zone on the platform; see picture)

[Image Removed]

Hi,

I believe your solution to be your best bet as there’s no built-in way to determine based movement updates synchronized across multiple characters.

Your solution ensures that all characters on the same base update at the same time making collisions more consistent. Testing with p.NetShowCorrections 1 shows the corrections being made causing the jittering when not in the green zone.

Most other threads discuss a platform vs character jitter which testing didn’t result in any solution regarding the mentioned problem and are things we can rule out.

Thread 1: Setting Network smoothing to disabled didn’t fix the jitter.

Thread 2: Ignoring Class Movement Error Checks and Correction just made the player characters slide off.

Documentation: Ensuring SetBase was set to the platform didn’t have any effect as GetMovementBase was already updating appropriately.

That being said there is an extensive document on Networked Movement in the Character Movement Component that offers an in-depth explanation on the topic.

The best practices for Networked Movement Abilities (CMC) offers best practices when it comes to debugging and general advice that could be beneficial to your situation.

If you’re looking for alternatives, Mover may be something to check out as it is intended to become the next gen approach to character movement.

Please let me know if you have any questions or comments!

Regards

Hi John,

Thank you for the reply. While I’m not totally happy with this solution, I’m at least optimistic to hear that you do not see any obvious problems with prematurely updating based movement prior to normal movement ticking. We indeed also had the other jitter issues you mentioned but have of course already implemented our own solutions.

Mover does sound great (and we understand it’s the future) but unfortunately it’s not a realistic option for us at this time.

At any rate, thank you for the support and I hope you have a great rest of your week.

Cheers,

Benjamin

Thanks for your reply and well wishes! If you have any other questions feel free to reach out here, I’ll be closing this case for now.

Have a great rest of your week as well!

Regards