There is also a workaround. Instead of wiring up the events between the input actions map, a player input component on a game object, and then your own script with event handlers in it, you can cut out the player input component completely and go with scripting the event handlers.
- On your input actions map, single click it (instead of double to open it) and view it in the inspector.
- Click the Generate C# Class checkbox, set the file and class name as desired, then click Apply (fig 1)
- Now in your input handling class with the OnMove() etc. methods in it, create and cache an instance of this new class during Awake. For the following steps, I’m calling my instance inputControl.
- In your class, add/edit the OnEnable() and OnDisable() standard unity events and accordingly call inputControl.Enable() and inputControl.Disable() in them.
- In your Awake method, after you created a new instance of the class, start hooking up your events using the same input action map definitions that you put into the UI of the input actions mapper (e.g. input map asset → Player → Move becomes inputControl.Player.Move and so on). See fig 2.
Fig 1:
Fig 2 - naive scenario:
public class SimpleMovement : MonoBehaviour {
private InputDefs inputControl;
[SerializeField] private float speed = 10f;
private void Awake() {
inputControl = new InputDefs(); // Create/cache a new instance of the input map
// This adds the handler method to the input actions map such
// that the IDE will see them connected
inputControl.Player.Move.performed += OnMove;
}
private void OnEnable() => inputControl.Enable();
private void OnDisable() => inputControl.Disable();
private Rigidbody rb;
private float movementX, movementY;
private void Start() {
rb = GetComponent<Rigidbody>();
}
// This will no longer show as an unused event/method
// Note that this uses the InputAction.CallbackContext by default instead of an InputValue arg
// Pretty much the same except you use ReadValue<T>() instead of Get<T>() on it.
private void OnMove(InputAction.CallbackContext input) {
var xy = input.ReadValue<Vector2>();
movementX = xy.x;
movementY = xy.y;
}
private void FixedUpdate()
{
var movement = new Vector3(movementX, 0.0f, movementY);
rb.AddForce(movement * speed);
}
}
End result:
In addition to the .performed operations on a mapped input configuration, there are also .cancelled operations you may want to hook a handler up to as well, so you can zero out or signify when the controls have been released again, for those long-press vs. short-press distinctions. You can re-use the same event handler method (e.g. OnMove()) for them and adjust the values accordingly, or give them their own separate event handler.