Configurar un mapa de acción dinámicamente

Actualización de la página :
Fecha de creación de la página :

Entorno de verificación

Windows
  • Ventanas 11
Unity Editor
  • 2020.3.25f1
Paquete del sistema de entrada
  • 1.2.0

Requisitos previos para esta sugerencia

Los siguientes ajustes se han realizado de antemano como premisa para la descripción de este consejo.

También debe estar familiarizado con los siguientes consejos:

Acerca de la configuración dinámica del mapa de acción

Es común agregar y establecer mapas de acción al proyecto por adelantado, En este caso, las asignaciones de botones del controlador se fijan durante la ejecución del juego y el usuario no puede cambiarlas libremente durante el juego. Esto se espera principalmente para juegos que requieren configuración de claves.

Esta sugerencia describe cómo cambiar arbitrariamente las asignaciones de teclas de un mapa de acciones en un script.

Gestión dinámica de cambios en el mapa de acciones

Esta vez, el script también establece el mapa de acción inicial, y el cambio del mapa de acción en el medio también se realiza en el script. Creo que este método se utiliza al cargar y establecer la configuración de clave guardada al iniciar el juego.

El contenido del ejemplo es para cambiar la asignación de teclas del mapa de acción al presionar el botón y para mostrar el contenido operado como texto. La colocación de los botones y el texto de visualización están dispuestos como se muestra en la figura, pero no son muy importantes, así que colóquelos libremente.

Proceso de configuración inicial del mapa de acciones

Cree un script. El nombre es arbitrario, pero en este caso InputActionMap es . Esta vez, todos los procesos se describirán aquí, pero en la producción real, divídalos de acuerdo con la creación del proyecto.

El script tiene este aspecto: En primer lugar, cree un mapa de acciones predeterminado al inicio.

using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;

public class InputActionMap : MonoBehaviour
{
  /// <summary>情報を表示させるテキストオブジェクト。</summary>
  [SerializeField] private Text TextObject;

  /// <summary>Move アクション用の定義。</summary>
  public InputAction MoveAction { get; set; }

  /// <summary>Attack アクション用の定義。</summary>
  public InputAction AttackAction { get; set; }

  private void Awake()
  {
    // Move アクションの作成
    MoveAction = new InputAction("Move");

    // バインド(キー割り当て)の追加
    // 設定する文字列の形式はアクションマップ設定画面の Path に表示される文字列となる
    MoveAction.AddBinding("<Gamepad>/leftStick");

    // キーボードに上下左右を割り当てるにはコンポジットの 2DVector を設定する
    MoveAction.AddCompositeBinding("2DVector")
        .With("Up", "<Keyboard>/upArrow")
        .With("Down", "<Keyboard>/downArrow")
        .With("Left", "<Keyboard>/leftArrow")
        .With("Right", "<Keyboard>/rightArrow");

    // Attack アクションの作成
    AttackAction = new InputAction("Attack");

    // バインド(キー割り当て)の追加
    AttackAction.AddBinding("<Gamepad>/buttonSouth");
    AttackAction.AddBinding("<Keyboard>/z");

    // 操作時のイベントを設定
    MoveAction.performed += context => OnMove(context);
    MoveAction.canceled += context => OnMove(context);
    AttackAction.performed += context => OnAttack(context);
    AttackAction.canceled += context => OnAttack(context);
  }

  private void OnEnable()
  {
    // オブジェクトが有効になったときにアクションマップを有効にする
    MoveAction.Enable();
    AttackAction.Enable();
  }

  private void OnDisable()
  {
    // アクションマップが誤動作しないようにオブジェクト終了時に無効にする
    MoveAction.Disable();
    AttackAction.Disable();
  }

  /// <summary>
  /// Move 操作を行ったときに呼ばれる。
  /// </summary>
  /// <param name="context">コールバック内容。</param>
  public void OnMove(InputAction.CallbackContext context)
  {
    var vec = context.ReadValue<Vector2>();
    TextObject.text = $"Move:({vec.x:f2}, {vec.y:f2})\n{TextObject.text}";
  }

  /// <summary>
  /// Move 操作を行ったときに呼ばれる。
  /// </summary>
  /// <param name="context">コールバック内容。</param>
  public void OnAttack(InputAction.CallbackContext context)
  {
    var value = context.ReadValueAsButton();
    TextObject.text = $"Attack:{value}\n{TextObject.text}";
  }
}

Primero, defina tantas acciones en la clase como desee InputAction implementar en el campo. Aquí, prepararemos los campos para "Mover" y "Atacar", que también se utilizaron en la explicación anterior del mapa de acción. Si el número de acciones aumenta, debe declarar ese número, pero si hay List Dictionary muchas, puede administrarlas con , , etc. No se usa aquí, pero si tienes tu propia InputActionMap clase, puedes administrarla allí.

Se realiza la creación de instancias y la asignación AddBinding de claves en el InputAction método denominado Awake al inicialización. Puede pensar en lo que está haciendo como un programa que agrega un enlace en la pantalla de configuración del mapa de acción. AddBinding La cadena especificada para Método, etc. es la misma que la cadena que se muestra en Ruta en la pantalla de configuración del mapa de acciones. Para mostrar una cadena de caracteres, pulse el botón "T" a la derecha.

El control de eventos llamado cuando se opera un botón es el mismo que el procesamiento de la versión con scripts de un mapa de acción normal. El proceso de devolución de llamada también se desvía tal cual.

// 操作時のイベントを設定
MoveAction.performed += context => OnMove(context);
MoveAction.canceled += context => OnMove(context);
AttackAction.performed += context => OnAttack(context);
AttackAction.canceled += context => OnAttack(context);
/// <summary>
/// Move 操作を行ったときに呼ばれる。
/// </summary>
/// <param name="context">コールバック内容。</param>
public void OnMove(InputAction.CallbackContext context)
{
  var vec = context.ReadValue<Vector2>();
  TextObject.text = $"Move:({vec.x:f2}, {vec.y:f2})\n{TextObject.text}";
}

Habilitar, Deshabilitar es InputAction una unidad, así que describa tantas acciones como desee. Si es problemático, puede manejarlo List con, etc.

private void OnEnable()
{
  // オブジェクトが有効になったときにアクションマップを有効にする
  MoveAction.Enable();
  AttackAction.Enable();
}

Después de EventSystem guardar el script, adjúntelo y configure un objeto de texto para su visualización.

Ejecute el juego y vea si aparece la información de entrada. El resultado debe ser el mismo que la versión con script del proceso estático del mapa de acciones.

Mapa de acción Procesamiento dinámico de cambios

Dado que el cambio dinámico del mapa de acción se realiza cuando se presiona el botón, defina el método al que se llamará cuando se presione el botón. OnClickButton Por ahora, lo dejaremos como .

// 省略

public class InputActionMap : MonoBehaviour
{
  // 省略

  /// <summary>
  /// ボタンをクリックしたときに呼ばれる。
  /// </summary>
  public void OnClickButton()
  {
  }
}

Establece el evento click para el botón.

El proceso de reescritura del mapa de acción es el siguiente:

/// <summary>
/// ボタンをクリックしたときに呼ばれる。
/// </summary>
public void OnClickButton()
{
  TextObject.text = "アクションマップを変更しました。";

  // Move アクションのキーを置き換える
  MoveAction.ApplyBindingOverride(new InputBinding { path = "<Gamepad>/leftStick", overridePath = "<Gamepad>/dpad" } );
  MoveAction.ApplyBindingOverride(new InputBinding { path = "<Keyboard>/upArrow", overridePath = "<Keyboard>/w" });
  MoveAction.ApplyBindingOverride(new InputBinding { path = "<Keyboard>/downArrow", overridePath = "<Keyboard>/s" });
  MoveAction.ApplyBindingOverride(new InputBinding { path = "<Keyboard>/leftArrow", overridePath = "<Keyboard>/a" });
  MoveAction.ApplyBindingOverride(new InputBinding { path = "<Keyboard>/rightArrow", overridePath = "<Keyboard>/d" });

  // Attack アクションのキーを置き換える
  AttackAction.ApplyBindingOverride(new InputBinding { path = "<Gamepad>/buttonSouth", overridePath = "<Gamepad>/buttonEast" });
  AttackAction.ApplyBindingOverride(new InputBinding { path = "<Keyboard>/z", overridePath = "<Keyboard>/space" });
}

Dado que se proporciona un método para ApplyBindingOverride cada acción, la ruta de acceso de la path tecla o botón que se inicializó en , overridePath Escriba la ruta de la tecla o botón que desea anular.

Por cierto, esto es solo establecer la ruta de sobrescritura, por lo que la ruta original permanece como está. Por ejemplo, en una acción Ataque, cambie la tecla z a la barra espaciadora. Además, si desea cambiar de espacio a tecla x, la descripción se sobrescribirá para la tecla z en lugar de basarse en el espacio, como se indica a continuación.

AttackAction.ApplyBindingOverride(new InputBinding { path = "<Keyboard>/z", overridePath = "<Keyboard>/x" });

Una vez guardado, ejecuta el juego y haz clic en el botón para ver si cambian las teclas o los botones con los que interactúas.

InputAction Esta vez, estamos cambiando el mapa de acción por el que creó una instancia de , También InputAction hay un script generado por la configuración del mapa de acción de la GUI, así que impleméntelo en el que sea fácil de hacer.