Menu
CoddyTech

Input Actions

Part of the Building Real Games section of Coddy's Unity journey. Lesson 47 of 60.

Testing keys one by one ties a script to the keyboard. An action names what the player does instead, and the project lists which keys, sticks and buttons trigger it. A new Unity 6 project ships with a set of them (the InputSystem_Actions asset, set as the project-wide actions), whose Player map has Move (WASD, the arrows and a gamepad's left stick), Look (the mouse or the right stick), Attack (the left mouse button and Enter), Interact (E, held), Crouch (C), Jump (Space and the gamepad's south button), Previous and Next (1 and 2) and Sprint (Left Shift). They are switched on from the start, and InputSystem.actions.FindAction("Jump") gets one by name. This side-view claw crane moves on x and y and grabs on Jump:

using UnityEngine;
using UnityEngine.InputSystem;

public class ClawCrane : MonoBehaviour
{
    public float speed = 3f;

    private InputAction moveAction;
    private InputAction jumpAction;

    void Start()
    {
        moveAction = InputSystem.actions.FindAction("Move");
        jumpAction = InputSystem.actions.FindAction("Jump");
    }

    void Update()
    {
        Vector2 input = moveAction.ReadValue<Vector2>();
        transform.position += new Vector3(input.x, input.y, 0f) * speed * Time.deltaTime;

        if (jumpAction.WasPressedThisFrame())
            Debug.Log("Grab!");
    }
}

The actions are found once, in Start, and kept in InputAction fields. Move gives a Vector2: x is right and left, y is up and down on the keys, and it is normalized, so W and D together give (0.71, 0.71) rather than (1, 1). The crane is a side view, so it uses that y for height; a game seen from above would use it for z. Button actions answer like keys: WasPressedThisFrame(), WasReleasedThisFrame() and IsPressed(). Two mistakes throw: a misspelled name makes FindAction return null (a NullReferenceException on the first read), and ReadValue<Vector3>() on Move throws an InvalidOperationException as soon as a key is held, because Move holds a Vector2.

challenge icon

Challenge

Medium

Walk the surveyor and plant flags with the project's actions.

  1. In Start(), set moveAction, jumpAction and attackAction with InputSystem.actions.FindAction("Move"), "Jump" and "Attack".
  2. In Update(), walk by moveAction.ReadValue<Vector2>() times speed, its y along z.
  3. Call Plant() when jumpAction.WasPressedThisFrame(), and PullUp() on an Attack press.

Press Play, plant three flags and click to pull one up. Then Check.

Try it yourself

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class Surveyor : MonoBehaviour
{
    public float speed = 4f;
    public int flags = 3;
    public GameObject flagPrefab;

    private InputAction moveAction;
    private InputAction jumpAction;
    private InputAction attackAction;
    private List<GameObject> planted = new List<GameObject>();

    void Start()
    {
        // find the Move, Jump and Attack actions
    }

    void Update()
    {
        // walk with Move, Plant() on a Jump press, PullUp() on an Attack press
    }

    void Plant()
    {
        if (flags == 0) return;
        Vector3 spot = new Vector3(transform.position.x, 0.75f, transform.position.z);
        planted.Add(Instantiate(flagPrefab, spot, Quaternion.identity));
        flags--;
        Debug.Log("Flags left: " + flags);
    }

    void PullUp()
    {
        if (planted.Count == 0) return;
        GameObject last = planted[planted.Count - 1];
        planted.RemoveAt(planted.Count - 1);
        Destroy(last);
        flags++;
        Debug.Log("Flags left: " + flags);
    }
}

All lessons in Building Real Games

Practice on your own: Unity playground