동적으로 작업 맵 설정

페이지 업데이트 :
페이지 생성 날짜 :

검증 환경

윈도우
  • 윈도우 11
Unity 에디터
  • 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 정의합니다. 여기서는 이전 액션 맵 설명에서도 사용했던 "Move"와 "Attack"에 대한 필드를 준비합니다. 액션의 개수가 늘어나면 그 개수를 선언해야 하지만, 많으면 List Dictionary , , , 등으로 관리할 수 있습니다. 여기서는 사용되지 않지만 자신의 InputActionMap 클래스가 있으면 거기에서 관리 할 수 있습니다.

초기화 시 호출 Awake 된 메서드의 InputAction 인스턴스화 및 키 할당 AddBinding 이 수행됩니다. 자신이 하고 있는 일을 액션 맵 설정 화면에 바인딩을 추가하는 프로그램으로 생각할 수 있습니다. AddBinding 메서드 등에 지정된 문자열은 액션 맵 설정 화면의 경로 에 표시되는 문자열과 동일합니다. 문자열을 표시하려면 오른쪽의 "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 이번에는 의 인스턴스를 만든 작업 맵을 변경합니다. GUI의 액션 맵 설정에 의해 생성 된 스크립트도 InputAction 있으므로, 쉽게 구현할 수 있습니다.