Description

When the character class is set to always relevant, if a client travels very far away from another character, such that the character is relevant but the component they're standing on is not (but also has not yet been garbage collected), then UCharacterMovementComponent::SimulateMovement() may run but fail to find a floor for this character and put them into the falling movement mode. If the simulated character remains idle such that their ReplicatedBasedMovement property does not change and replicate again, then the client may return to find that the character has fallen out of the world or is stuck in the falling movement mode while standing on the ground. I've included more thorough repro steps starting from a new UE5 project above.

Our fix was to add another early out to UCharacterMovementComponent::SimulateMovement() after the IsBaseUnresolved() check. This checks the simulated character's ReplicatedBasedMovement for bServerHasBaseComponent=true and !MovementBase->HasBegunPlay(), which seems sufficient to catch the case in which the floor is no longer relevant on the client but has not yet been nulled out.

(Heavily paraphrased from licensee)

Steps to Reproduce

Steps to Reproduce
1. From the project browser, create a new project.
2. When the editor opens, create a new Open World level.
3. Open BP_FirstPersonCharacter and enable 'Always Relevant' in its Class Defaults. Compile.
4. Start PIE, Play as Listen Server with 2 players.
5. Enter the following console commands on the client's instance:
5.a. "DisplayAll CharacterMovementComponent MovementMode"
5.b. "DisplayAll Character ReplicatedBasedMovement"
5.c. "DisplayAll Character Location"
6. Have the client walk to the edge of the landscape. (May also want to enter "slomo 10" on the server's instance to speed this up.)
7. Once the client is sufficiently far away (~100000 units), they should see the host's MovementMode change to MOVE_Falling.
8. Wait for garbage collection or use "obj gc" to invoke garbage collection immediately on the client. This nulls out the replicated MovementBase so SimulateMovement() will early out.
9. Return to the host player at the center of the level.
10. The host can now walk around and the client will still see them in MOVE_Falling until the next time something happens to replicate ReplicatedBasedMovement again, such as jumping and landing or walking onto a different part of the landscape.

Have Comments or More Details?

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

1
Login to Vote

Backlogged
ComponentUE - Gameplay - Player Movement
Affects Versions5.3.2
Target Fix5.5
CreatedFeb 26, 2024
UpdatedMar 1, 2024