Динамічне настроювання карти дій

Сторінка оновлюється :
Дата створення сторінки :

Середовище перевірки

Вікна
  • вікна 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 хочете реалізувати в полі. Тут ми підготуємо поля для "Переміщення" та "Атаки", які також використовувалися в попередньому поясненні карти дій. Якщо кількість дій збільшується, потрібно оголосити це число, але якщо їх List Dictionary багато, керувати ними можна за допомогою , і т.д. Він тут не використовується, але якщо у вас є свій InputActionMap клас, ви можете керувати ним там.

Виконується екземпляр і призначення AddBinding ключа в методіInputAction, що викликається Awake при ініціалізації. Ви можете думати про те, що ви робите, як про програму, яка додає прив'язку на екрані налаштування карти дій. AddBinding Рядок, указаний для Method тощо, такий самий, як рядок, що відображається в 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}";
}

Enable, Disable - це 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 сценарій, згенерований налаштуванням карти дій графічного інтерфейсу, тому, будь ласка, реалізуйте його в тому, який легко зробити.