Unity Term Book
スクリプティングとライフサイクル

Input System

Unity の新しい Input System は柔軟なキーリマップ、複数デバイス、イベント駆動 Action を備え、旧 Input.GetKey() ポーリングを置き換えます。Action Map 切替、イベント購読と解除、PerformInteractiveRebinding による再バインド基礎を学べます。

想像してみてください...

旧 Input System はスタッフが毎 0.016 秒電話して「客は来た?」と聞く(ポーリング)のようです。新 Input System呼び鈴(イベント)を付け——押されたときだけ聞こえます。Action Maps は配電盤のようで、同じ「Confirm」ボタンがメニューでは Navigate Accept、ゲームプレイでは Jump になります。`if (context == menu)` のスパゲッティは不要です。

概念の詳細

Input Actions Asset はすべてのバインディングを持つ .inputactions ファイルです。構成は Action Maps(Gameplay、UI、Vehicle…)→ 各 Map に Actions(Move、Jump、Fire…)→ 各 Action に Bindings(キー、スティック、ゲームパッドボタン…)。

イベント駆動: action.startedaction.performedaction.canceled を購読。 値は context.ReadValue<Vector2>()。Update ポーリングは不要です。

Player Input コンポーネント: GameObject に付けて イベントを自動配線。Messages、C# Events、Unity Events に対応します。

ランタイムリマップ: action.AddBinding()InputActionRebindingExtensions.PerformInteractiveRebinding() で、 Settings メニューからキーバインド変更が可能です。

ダイアグラム:Input System アーキテクチャ

⌨️ Keyboard
🎮 Gamepad
📱 Touch
🖱 Mouse
↓ Device Input

Input Actions Asset (.inputactions)

Action Map: GameplayAction Map: UIAction Map: Vehicle
↓ Binding resolution

Actions: Move, Jump, Fire, Interact...

started / performed / canceled events

↓ C# Events

PlayerController

OnMove(ctx)

UINavigator

OnNavigate(ctx)

VehicleDriver

OnSteer(ctx)

ハンズオン手順

1

Input System パッケージをインストール

Window → Package Manager → Input System → Install。求められたら再起動。

2

Input Actions Asset を作成

Assets → Create → Input Actions。Action Maps、Actions、各キー/ボタンの Bindings を追加。

3

C# クラスを生成

.inputactions を選択 → Inspector → "Generate C# Class" にチェック → Apply → Unity がラッパークラスを出力。

4

イベントを購読/解除

OnEnable:_actions.Gameplay.Jump.performed += OnJump; OnDisable:同じ方法で解除。

インタラクティブシミュレーター

キー(または下のボタン)を押し、アクティブな Action Map の正しいリスナーへイベントが届くのを確認しましょう。

Active Map:

Virtual Input

Event Log

キーを押してイベントを見る...

Map: Gameplay|Events fired: 0

コード例

基本

生成された C# クラスとイベント購読を使う。

using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerController : MonoBehaviour
{
  private GameControls _actions; // Generated C# class
  private Rigidbody    _rb;
  private Vector2      _moveInput;

  void Awake()
  {
      _rb      = GetComponent<Rigidbody>();
      _actions = new GameControls();
  }

  void OnEnable()
  {
      _actions.Gameplay.Enable();
      _actions.Gameplay.Move.performed  += OnMove;
      _actions.Gameplay.Move.canceled   += OnMove;
      _actions.Gameplay.Jump.performed  += OnJump;
  }

  void OnDisable()
  {
      _actions.Gameplay.Move.performed  -= OnMove;
      _actions.Gameplay.Move.canceled   -= OnMove;
      _actions.Gameplay.Jump.performed  -= OnJump;
      _actions.Gameplay.Disable();
  }

  void OnMove(InputAction.CallbackContext ctx)
      => _moveInput = ctx.ReadValue<Vector2>();

  void OnJump(InputAction.CallbackContext ctx)
      => _rb.AddForce(Vector3.up * 5f, ForceMode.Impulse);

  void FixedUpdate()
      => _rb.velocity = new Vector3(_moveInput.x * 5f, _rb.velocity.y, _moveInput.y * 5f);
}

コード例

上級

インタラクティブ再バインド——ランタイムでキー変更を許可。

using UnityEngine;
using UnityEngine.InputSystem;
using TMPro;

public class KeyRebinder : MonoBehaviour
{
  [SerializeField] private InputActionReference jumpAction;
  [SerializeField] private TextMeshProUGUI bindingLabel;
  private InputActionRebindingExtensions.RebindingOperation _rebindOp;

  public void StartRebind()
  {
      jumpAction.action.Disable();
      bindingLabel.text = "Press any key...";

      _rebindOp = jumpAction.action
          .PerformInteractiveRebinding()
          .WithControlsExcluding("Mouse")
          .OnMatchWaitForAnother(0.1f)
          .OnComplete(op => {
              op.Dispose();
              jumpAction.action.Enable();
              bindingLabel.text = InputControlPath.ToHumanReadableString(
                  jumpAction.action.bindings[0].effectivePath);
              // Persist binding overrides
              PlayerPrefs.SetString("JumpBinding", jumpAction.action.SaveBindingOverridesAsJson());
          })
          .Start();
  }
}

📌 要点

  • 文脈に応じて ActionMaps を Enable/Disable(Gameplay ↔ UI)
  • 購読は OnEnable、解除は OnDisable
  • performed = 押下;canceled = 離す
  • C# クラス生成 → きれいな API + IntelliSense

⚠️ よくあるミス

  • ❌ Action Map の Enable() を忘れる

    購読後も Action が発火しない——サイレント失敗

    ✅ OnEnable で _actions.Gameplay.Enable()

  • ❌ OnDisable で Unsubscribe を忘れる

    メモリリーク——破棄済みオブジェクトへイベントが飛ぶ

    ✅ OnEnable/OnDisable で Subscribe/Unsubscribe を必ず対にする