Characters on client constantly falling in place

Since this seems to be the only reference to this topic I could find I thought I’d provide my solution in case it helps someone.

The key issue we discovered is that when NavWalking on a client the capsule stops colliding against WorldStatic/Dynamic and it uses the collision parameters of the capsule to detect the floor, so Unreal decides that it must be falling. But once it starts falling the collisions are restored, so it starts NavWalking again. So it loses it’s collisions again, and must be falling, etc. This only happens on SimulatedProxies though, because of Unreal reasons.

In our project we use a custom movement component so our solutions involve overriding functions in C++. I’ll add a potential blueprint solution to the end but I haven’t tested that.

The solution we used is to override UCharacterMovementComponent::FloorSweepTest() and force it to use the correct FCollisionResponseParams when performing a test while the owner role is ROLE_SimulatedProxy and the movement mode is MOVE_NavWalking. Here’s a bare bones example:

bool UCustomCharacterMovementComponent::FloorSweepTest(FHitResult& OutHit, const FVector& Start, const FVector& End,
	ECollisionChannel TraceChannel, const FCollisionShape& CollisionShape, const FCollisionQueryParams& Params,
	const FCollisionResponseParams& ResponseParam) const
{
	// If we aren't a client or NavWalking
	if (GetOwnerRole() != ROLE_SimulatedProxy || MovementMode != MOVE_NavWalking)
	{
		// Continue normally
		return Super::FloorSweepTest(OutHit, Start, End, TraceChannel, CollisionShape, Params, ResponseParam);
	}

	// Otherwise use different response params
	return Super::FloorSweepTest(OutHit, Start, End, TraceChannel, CollisionShape, Params, FCollisionResponseParams::DefaultResponseParam);
}

Another solution is to override UCharacterMovementComponent::SetNavWalkingPhysics so it doesn’t set the collision response to the ECC_WorldStatic and ECC_WorldDynamic channels to ECR_Ignore. If you also want to stop them from phasing through solid geometry then this might be best for you, but it comes at a performance cost.

Finally, if you can only use blueprints you can potentially fake the last solution by implementing the OnMovementModeChanged event, and then blocking the correct channels in response. I’m not 100% sure on that one though because I haven’t tested it myself. Something like this:

YMMV

6 Likes