Unity:Manuales:Input System

De WikiGarcia

El nuevo sistema de Input de Unity permite facilitar el manejo de entradas del usuario, en lugar de configurar cosas para cada dispositivo (touchpad, control, flechas), todo se configura desde el sistema y funcionan de la misma forma.

Importar el paquete

  • El paquete se importa desde el Package Manager->Input System.
  • Aparecerá una ventana preguntando si se desea deshabilitar el sistema anterior para el reproductor, salir sin seleccionar nada.
  • Dirigirse a Edit->Project Settings...->Player->Other Settings->Active Input Handling->Both.

Crear el Asset

  • Create->Input Actions

Al abrir el asset se muestra una ventana donde se declaran las acciones.

  • Action Maps: Para agrupar acciones por separado (Ej: Si el conjunto de acciones cambia si el personaje está a pie, en un auto, etc.)
  • Actions: Lista de acciones. Cada acción se le puede asignar un binding que sería la tecla que se le asocia. (Ej: saltar, disparar, mover, etc).
  • Properties: Se selecciona el tipo de acción.

Unity Events

  1. En el GameObject que se le va a asociar la acción agregarle el componente Player Input.
  2. Asignarle el asset de las acciones en el campo Actions y seleccionar el mapa que va a usar.
  3. En el Behavior seleccionar Invoke Unity Event, esto nos permite asociar la acción a una función de Unity que se encuentre en un GameObject.
  4. Crear el método en el GameObject y asociarlo en el Behavior.

C# Events

Es similar a con eventos de Unity, solo que las asociaciones a los eventos se hacen desde código.

  1. En el Behavior seleccionar Invoke C sharp Event.
  2. En el script donde queramos escuchar el evento crear las funciones necesarias.
public class Player : MonoBehaviour
{
    public PlayerInput playerInput;

    private void Awake()
    {
        playerInput = GetComponent<PlayerInput>();
        
        // El evento se dispara para todas las acciones,
        // por lo que hay que filtrarlo en la funcion
        playerInput.onActionTriggered += PlayerInput_onActionTriggered;
    }

    private void PlayerInput_onActionTriggered(InputAction.CallbackContext context)
    {
        Debug.Log(context);
    }
}

Interacciones

Se puede definir bajo qué condiciones se lanza el evento: Tiempo de mantener presionado, presionar varias veces, presionar lentamente, etc.

Usar todo desde script

Para mayor versatilidad es posible generar una clase del PlayerInputActions y subscribirse a los eventos desde el script, esto nos permite tener un editor más limpio y poder habilitar/deshabilitar acciones desde el código.

  1. Seleccionar el asset con las acciones
  2. Seleccionar Generate C# class
  3. Se puede dejar todo por defecto y dar Apply.

Para suscribirse a los eventos desde código:

public class Player : MonoBehaviour
{

    private void Awake()
    {
        PlayerInputActions playerInputActions = new PlayerInputActions();
        playerInputActions.Default.Enable(); // Cambiar 'Default' por el ActionMap correcto
        playerInputActions.Default.Fire.performed += Fire;
    }
    public void Fire(InputAction.CallbackContext context)
    {
        if (context.performed)
        {
            Debug.Log("FIRE!");
        }
    }
}

Con este método ya no es necesario el componente Player Input en el GameOpbject que escucha las acciones.

Usando valores

Cuando en las propiedades de la acción se usa Value en lugar de Button, es común que se use para acciones continuas (como el movimiento de un jugador) en lugar de acciones momentáneas (como apretar el gatillo), es por ello que es común leer el valor en cada frame en lugar de esperar a que el evento se lance.

public class Player : MonoBehaviour
{
    private Rigidbody playerRigidbody;
    private PlayerInputActions playerInputActions;

    private void Awake()
    {
        playerRigidbody = GetComponent<Rigidbody>();
        playerInputActions = new PlayerInputActions();
    }

    public void Update()
    {
        Vector2 inputVector = playerInputActions.Default.Movement.ReadValue<Vector2>();
        float speed = 1f;
        playerRigidbody.AddForce(new Vector3(inputVector.x, 0f, inputVector.y) * speed, ForceMode.Force);
    }
}

Crear un Esquema

Los esquemas sirven para diferenciar los tipos de dipositivos de entrada (teclado, keypad, control, etc.).

  1. En la esquina superior izquierda No Control Schemes->Add Control Scheme
  2. Ponerle un nombre y en la lista agregar el tipo de control deseado, ej: Keyboard.
  3. En cada una de las acciones que se desee agregar al esquema seleccionarla y en Properties checar el recuadro del esquema desado.

Cambiar entre esquemas

El cambio se puede hacer desde el código con el método:

// Si se usa el Componente PlayerInput
playerInput.SwitchCurrentActionMap("Map");

// Si se usa desde C#
playerInputActions.Default.Disable(); // Desactivamos el mapa actual
playerInputActions.UI.Enable(); // Habilitamos el nuevo mapa

Remapear teclas

Esta característica se usa para que el jugador pueda personalizar sus controles.

playerInputActions.Default.Disable();
// Hace que la próxima tecla/botón presionado se vincule con la acción
playerInputActions.Default.Fire.performInteractiveRebinding()
    .OnComplete(callback => {
        Debug.Log(callback);
        callback.Dispose();
        playerInputActions.Default.Enable();
    })
    .Start();

Guardar teclas remapeadas

void SaveUserRebindings(PlayerInput player)
{
    var rebinds = player.actions.SaveBindingOverridesAsJson();
    PlayerPrefs.SetString("rebinds", rebinds);
}

void LoadUserRebindings(PlayerInput player)
{
    var rebinds = PlayerPrefs.GetString("rebinds");
    player.actions.LoadBindingsOverridesFromJson(rebinds);
}

Pantalla touch

Para facilitar el manejo de entradas touch, el Input System cuenta con dos componentes interesantes.

Para el joystick:

  1. Crear un canvas
  2. Crear una imagen simple para el joystick.
  3. Add Component->On-Screen Stick
  4. Editar Control Path seleccionar el tipo de entrada que se va a simular, ej: Left Stick (Gamepad).

Para los botones:

  1. Crear una imagen simple en el canvas
  2. Add Component->On-Screen Button
  3. Editar Control Path seleccionar el tipo de entrada que se va a simular, ej: South Button (Gamepad).