動態設置操作映射

更新頁 :
頁面創建日期 :

驗證環境

窗戶
  • 視窗 11
統一編輯器
  • 2020.3.25f1
輸入系統包
  • 1.2.0

此提示的先決條件

作為此提示描述的前提,已預先進行了以下設置。

您還應該熟悉以下提示:

關於動態操作映射配置

通常提前為專案添加和設置操作圖, 在這種情況下,控制器按鈕分配在遊戲執行期間是固定的,用戶在遊戲過程中無法自由更改。 這主要是需要金鑰配置的遊戲。

此提示介紹如何任意更改文本中操作映射的鍵分配。

動態操作圖更改處理

這一次,初始動作圖也是由腳本設置的,中間的動作圖更改也是在腳本中完成的。 我認為在載入和設定遊戲啟動時保存的金鑰配置時使用此方法。

示例的內容是在按下按鈕時更改操作映射的鍵分配,以及將操作的內容顯示為文本。 按鈕位置和顯示文本如圖所示排列,但它們不是很重要,因此請自由放置它們。

操作映射初始配置過程

創建腳本。 名稱是任意的,但在這種情況下 InputActionMap 是. 這次,所有的過程都會在這裡描述,但在實際生產中,請根據專案的創建進行劃分。

文稿如下所示: 首先,在啟動時創建預設操作映射。

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

首先,在類中定義要在欄位中實現的任意InputAction數量的操作。 在這裡,我們將準備“移動”和“攻擊”的字段,它們在前面的操作地圖說明中也使用過。 如果操作數量增加,則需要聲明該數位,但如果操作ListDictionary數量很多,則可以使用 、、等來管理它們。 這裡不使用它,但是如果您有自己的InputActionMap類,則可以在那裡管理它。

在初始化時調用 Awake 的方法 InputAction 中執行實例化和金鑰分配 AddBinding 。 您可以將您正在執行的操作視為在操作映射設定螢幕上添加綁定的程式。 AddBinding 為方法等指定的字串與操作映射設置螢幕上的Path中顯示的字串相同。 要顯示字串,請按右側的“T”按鈕。

操作按鈕時調用的事件處理與正常操作圖的腳本版本的處理相同。 回調過程也會按原樣轉移。

// 操作時のイベントを設定
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}";
}

啟用,禁用是一個 InputAction 單元,因此請根據需要描述任意數量的操作。 如果很麻煩,你可以用等來管理它 List

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

保存文稿后 EventSystem ,將其附加到文本物件並配置要顯示的文字物件。

運行遊戲並查看是否顯示輸入資訊。 結果應與操作映射靜態進程的腳本版本相同。

操作映射動態更改處理

由於操作映射的動態更改是在按下按鈕時完成的,因此定義在按下按鈕時將調用的方法。 OnClickButton 現在,我們將它保留為 .

// 省略

public class InputActionMap : MonoBehaviour
{
  // 省略

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

設置按鈕的按兩下事件。

動作對應重寫過程如下:

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

由於為每個操作提供了一個 ApplyBindingOverride 方法, path 因此初始化為的鍵或按鈕的路徑 , overridePath 寫入要覆蓋的鍵或按鈕的路徑。

順便說一下,這隻是設置覆蓋路徑,因此原始路徑保持原樣。 例如,在攻擊操作中,將 z 鍵更改為空格鍵。 此外,如果要從空格更改為x鍵,則將覆蓋z鍵的描述,而不是基於空格,如下所示。

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

保存后,運行遊戲並按下按鈕以查看與您交互的鍵或按鈕是否更改。

InputAction這一次,我們將更改創建 , 的實例的操作映射 還有一個InputAction由GUI的動作圖設置生成的腳本,因此請在易於操作的腳本中實現它。