Movement Types define the target rotation of the character as well as what horizontal and forward inputs should be passed to the character. It is then up to the character controller to act on this target rotation and input vector to actually move the character.  Just because a value is passed to the character controller doesn’t mean the controller will act on it. For example, if the movement type says the character should move forward but there is a wall in front of the character then the character will not move forward.

Look Source Error

The error below will appear if the Movement Type is not attached to a Look Source. If the error is occurring in a single player game the Camera Controller can be attached as a Look Source. The Local Look Source component is used for AI agents. For multiplayer characters the networking implementation has its own remote look source.

Error: There is no look source attached to the character. Ensure the character has a look source attached. For player characters the look source is the Camera Controller, and AI agents use the Local Look Source.

Create New Movement Types

In most cases you don’t need to create a new Movement Type but if you do it’s a fairly easy process. New Movement Types can be created by inheriting the MovementType class and implementing one property and two methods:

/// <summary>
/// Property that returns true if the Movement Type is a first person movement type.
/// </summary>
/// <returns>True if the movement type is a first person movement type.</returns>
bool FirstPersonPerspective

/// <summary>
/// Returns the delta yaw rotation of the character.
/// </summary>
/// <param name="characterHorizontalMovement">The character's horizontal movement.</param>
/// <param name="characterForwardMovement">The character's forward movement.</param>
/// <param name="cameraHorizontalMovement">The camera's horizontal movement.</param>
/// <param name="cameraVerticalMovement">The camera's vertical movement.</param>
/// <returns>The delta yaw rotation of the character.</returns>
float GetDeltaYawRotation(float characterHorizontalMovement, float characterForwardMovement, float cameraHorizontalMovement, float cameraVerticalMovement)

/// <summary>
/// Gets the controller's input vector relative to the movement type.
/// </summary>
/// <param name="inputVector">The current input vector.</param>
/// <returns>The updated input vector.</returns>
Vector2 GetInputVector(Vector2 inputVector)

The GetDeltaYawRotation method returns the difference between the character’s current yaw rotation and the target yaw rotation. This rotation can depend on the camera’s rotation or it can be completely independent of the camera.


Returns the vector that will be used to actually move the character. The input vector is a Vector2 with the x value representing the horizontal movement and the y value representing forward movement.  A lot of Movement Types just return the inputted vector but in some cases (such as Top Down or 2.5D) the input vector should be adjusted based on the camera’s rotation.


The following Movement Type is an example of a complete movement type that prevents the character from rotating and also does not modify the input vector. This means when the character moves they will move relative to the character’s rotation.

using Opsive.UltimateCharacterController.Character.MovementTypes;

public class MyMovementType : MovementType
    public override bool FirstPersonPerspective { get { return false; } }

    public override float GetDeltaYawRotation(float characterHorizontalMovement, float characterForwardMovement, float cameraHorizontalMovement, float cameraVerticalMovement)
        return 0;

    public override Vector2 GetInputVector(Vector2 inputVector)
        return inputVector;