Input

Unity has two different systems that scripts can use to read player input from devices like keyboard, mouse, and game controllers:

  • The legacy Input Manager is the old system which is built into Unity itself.
  • The Input System Package is a newer system which is released as an optional package that can be added to your project.

In a game project you would generally pick one system or the other (the Input System Package is generally recommended), but the Animancer examples need to work in projects using either system so they manage all their input via the ExampleInput script (located in Assets/Plugins/Animancer/Examples/Code) which uses Conditional Compilation to determine which system to use. For example:

/// <summary>Was the left mouse button pressed this frame?</summary>
public static bool LeftMouseDown
#if ENABLE_INPUT_SYSTEM// If the Input System Package is active it will use this code:
    => Mouse.current.leftButton.wasPressedThisFrame;
#else// Otherwise it will use this code:
    => Input.GetMouseButtonDown(0);
#endif

This allows the other example scripts to simply check if (ExampleInput.LeftMouseDown) without knowing or caring which input system is being used.

Movement

Most inputs have a direct analogue in both systems so they look similar to the above example, but directional movement using the WASD keys is a bit more complicated. Both systems could manually check each of those individual keys and build an appropriate result, but that's not the recommended approach in either system.

The legacy Input Manager has "Virtual Axes" which take a combination of keys and output a result between -1 and 1.

  • The "Horizontal" axis uses the D key for its positive value and A for negative, so:
    • Holding nothing = 0.
    • Holding D = 1.
    • Holding A = -1.
    • Holding D and A = 0.
  • The "Vertical" axis is the same for W and S.
  • The keys used by these axes can be modified via Edit/Project Settings/Input Manager.
  • Input.GetAxis applies some smoothing to the value to make it change gradually over time, which we don't want so we use Input.GetAxisRaw instead.
  • So the code simply constructs a Vector using those two axes:
public static Vector2 WASD
    => new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));

The Input System Package has "Input Actions" which are somewhat similar to "Virtual Axes".

  • They would normally be defined in an Input Action Asset to properly take advantage of the flexibility of the new system, but for the sake of simplicity in these examples we are just creating the action in code:
private static InputAction _WasdAction;

public static Vector2 WASD
{
    get
    {
        if (_WasdAction == null)
        {
            _WasdAction = new InputAction(nameof(Movement), InputActionType.Value);
            _WasdAction.AddCompositeBinding("2DVector")
                .With("Up", "<Keyboard>/w")
                .With("Down", "<Keyboard>/s")
                .With("Left", "<Keyboard>/a")
                .With("Right", "<Keyboard>/d");
            _WasdAction.Enable();
        }

        return _WasdAction.ReadValue<Vector2>();
    }
}