Character Movement in X, Y, and Z Direction



I'm trying to develop a game where a character can move in the X, Y, and Z directions based on user input (let's say for sake of argument, there are three axes values and each axes determines the velocity the player should be moving in the X, Y, or Z direction). It is my current understanding that the UltimateCharacterLocomotion only uses a Vector2 for input to determine movement. This would allow me to move in the X and Y direction but not the Z direction.

My initial thinking was that I could create an ability to implement this, but I am running into the following challenge. After looking at the Ability class, my first inclination is:
  1. Override the UpdatePosition() function and use AddForce(...) to apply an incremental external force based on the value of each axes at the current frame minus the value of the axes at the previous frame. However, it's not clear to me that this would work, because in DeflectVerticalCollisions() the Y component of the external force is set to zero if the player collides with another object. So as an example, if the value of Y input axes is 0.4, and that applies an external force of 0.4, then DeflectVerticalCollisions() will set the external force in the Y direction to 0. Then if the player changes the Y input to 0.3, it will decrement the external force by 0.1, resulting in a external force of -0.1, which will move the character down in the Y direction.
  2. The second approach would be to modify the m_MotorThrottle in my ability, but it seems like the UpdateMotorThrottle() function in CharacterLocomotion.cs would reset any value I set m_MotorThrottle to.
Therefore, I am a little bit stumped at how I should approach this problem, without making significant changes to the source code for CharacterLocomotion.cs. Any ideas on how I can tackle this particular problem?


Well-known member
As you've discovered the character controller is specifically designed for movement along the X/Z axes and changing this would require modifying a lot of the movement/physics code in CharacterLocomotion. I know that's not much of a helpful answer but there really isn't a simple starting place I can point to.


Staff member
I had the same issue as I required a fly ability, which is a lot of 3D :) Justin pointed me to the swim ability from the swimming add-on. I used a modified version for my bird. It's a 3rd person adventure type of movement where the mouse provides direction through the look source /camera direction. Maybe, this helps.


Hello, quick update here, I ended up implementing my x, y, and z movement in an ability where I am trying to update the positions in UpdatePosition(). However, I am running into an issue where after adding an AnimationMonitor to my object, the following function never calls UpdatePositionAndRotation().

        private void UpdatePositionAndRotation(bool fromAnimatorMove)
            if (m_AnimatorMonitor != null && m_AnimatorMonitor.AnimatorEnabled) {
                // When the character is being moved manually it should always be updated within the main Move loop.
                if (fromAnimatorMove == m_ManualMove) {


I tried to set m_ManualMove to true while the ability is active, but it didn't seem like that worked either. I am not trying to use root motion, as I want to use the same animation regardless of how fast the ability tells the character to move. I also found AnimationMotion but that doesn't quite seem to be a great fit either.

Should I just move my code to Update() instead of UpdatePosition()? Why is CharacterLocomotion designed to block calling UpdatePositionAndRotation() for my use case? Or am I missing something that would trigger OnAnimatorMove()?


I realized that changing to Update() won't work since I am using AddForce in UpdatePosition(). OnAnimatorMove() is not called at all in my use case. It doesn't look like I have any choice but to disable this set of code unless anyone has any suggestions / can help me understand the purpose of the if statements in the code section I copied and pasted from above.