Camera-dependent inverted movement when walking on ceilings (custom gravity, UE5)

Hello everyone,

I’ve been working for some time on a system where a character can walk on any surface.
The system works well overall, and gravity is correctly computed using line traces.

I’m currently facing a major issue when the character is walking on the ceiling, i.e. when gravity is (X=0, Y=0, Z=1).

On the attached video, I’m only pressing the forward movement input. However, when gravity is set to (0,0,1), the behavior depends on the camera orientation:

  • If the camera is facing the X axis, movement works as expected.

  • If the camera is facing the Y axis, the controls become completely inverted.

This is not an input issue, but appears to be a reference frame / rotation problem caused by how movement direction is computed relative to gravity and camera orientation.

Technical context:

  • Unreal Engine 5.6

  • Blueprint only

  • Movement is based on Add Movement Input

  • I compute a custom rotation using a function called “Get Gravity World Rotation”, which is applied after Get Control Rotation, before being used to drive movement.

  • All relevant Blueprints are shown in links below :backhand_index_pointing_down::backhand_index_pointing_down:

Question:
What is the correct way to compute a movement direction that remains consistent regardless of camera orientation when gravity is inverted?
More specifically, how should the movement basis (forward/right vectors) be reconstructed when walking on ceilings, to avoid axis inversion issues?

Get Gravity World Rotation Blueprint
Movement Input with Gravity

Video :

Hey @Waabs how are you?

Your diagnosis is correct! You’re running into a basis reconstruction problem, not an input one.

This happens because the game is trying to decide “forward” and “right” using rotations that assume the world has a fixed up direction (Z up). When the character is upside down, those rotations become ambiguous, so depending on where the camera is looking, left and right can flip.

To solve this issue, you should rebuild the movement directions directly from vectors, instead of using rotations.
You can do that by treating gravity as the definition of “down”, and the opposite of it as “up”. Taking the camera’s forward direction and flatten it onto the surface the character is walking on. And computing a “right” direction that is perpendicular to both “up” and “forward”.

The implementation will look like this:
Function to set the correct values:

IA_Move implementation:

With these changes, “forward” and “right” will always be consistent, no matter if the character is on the floor, a wall, or the ceiling, as you won’t be rotating the world to match gravity but rebuilding the movement directions using gravity itself.

Hope this helps you! And please let me know if it worked!