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