Diferencia entre revisiones de «Unity:Manuales:Input System»

De WikiGarcia
Línea 47: Línea 47:
     {
     {
         Debug.Log(context);
         Debug.Log(context);
    }
}
</pre>
= 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.
# Seleccionar el asset con las acciones
# Seleccionar ''Generate C# class''
# Se puede dejar todo por defecto y dar ''Apply''.
Para suscribirse a los eventos desde código:
<pre>
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!");
        }
    }
}
</pre>
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.
<pre>
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);
     }
     }
}
}
</pre>
</pre>

Revisión del 18:45 15 nov 2021

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);
    }
}