概要
動作確認環境: Unity 2022.3 LTS / Unity 6
「キーボードでもゲームパッドでも操作できるようにしたい」「プレイヤーがキー配置を変更できるようにしたい」――こんな要望を実現しようとして、旧Input Systemで苦労した経験はありませんか?
New Input System は、Unity 2019から導入された次世代の入力処理システムです。Input Actions という抽象化された概念を使って、デバイスに依存しない柔軟な入力処理を実現します。
インストールと初期設定
パッケージのインストール
Window > Package Managerを開く- 左上のドロップダウンから
Unity Registryを選択 Input Systemを検索してインストール- 再起動を促すダイアログが表示されたら「Yes」 をクリック
Active Input Handlingの設定
Edit > Project Settings > Playerを開くOther Settings > Configuration > Active Input Handlingを確認- Both または Input System Package (New) を選択
- エディタが再起動される
Both: 旧Input Systemと新Input Systemの両方が使用可能。移行期間中に便利です。
旧Input Systemとの違い
旧Input Systemの問題点
- デバイスごとに個別のコードが必要
- キーバインドのカスタマイズが困難
- マルチプラットフォーム対応が大変
- ローカルマルチプレイヤー対応が困難
New Input Systemの利点
- デバイス非依存の実装 - 同じコードで複数デバイスに対応
- マルチプラットフォーム対応 - 設定ファイルで一元管理
- キーバインドのカスタマイズ - 標準機能として提供
- ローカルマルチプレイヤー対応 - Player Inputコンポーネントで簡単に実装
- 複雑な入力パターン - 長押し、ダブルクリックなどを設定だけで実現
New Input Systemの構成要素
| 要素 | 説明 |
|---|---|
| Input Actions Asset | 入力設定を保存するファイル |
| Action Map | 関連するActionをグループ化したもの |
| Action | 操作の単位(移動、ジャンプなど) |
| Binding | Actionと実際の入力デバイスを結びつけるもの |
| Player Input | 入力イベントを受け取るコンポーネント |
Action Type
| タイプ | 用途 |
|---|---|
| Value | 連続的な値(移動スティック、トリガーなど) |
| Button | ボタンの押下状態(ジャンプ、攻撃など) |
| Pass-through | 入力をそのまま伝える(複数入力点の処理) |
Input Actionsの作成と設定
Input Actions Assetの作成
- Projectウィンドウで右クリック
Create > Input Actionsを選択- アセットをダブルクリックして編集ウィンドウを開く
Action Mapの作成
左上の+ボタンをクリックして、新しいAction Mapを追加(例:「Player」)
Actionの作成
- Action Mapを選択した状態で
+ボタンをクリック - Action名を入力(例:「Move」「Jump」)
- Action TypeとControl Typeを設定
Bindingの追加
WASDキーの設定例:
- 「Move」Actionを選択
+ボタンからAdd Up/Down/Left/Right Compositeを選択- Up: W、Down: S、Left: A、Right: Dを設定
ゲームパッド左スティックの追加:
- 同じ「Move」Actionを選択
+ボタンからAdd Bindingを選択- Pathで
Gamepad > Left Stickを選択
マルチデバイス対応: 同じActionに複数のBindingを追加することで、キーボードでもゲームパッドでも同じコードで動作します。
C# Classの生成(推奨)
Input Actions Assetからタイプセーフなクラスを自動生成できます。
- ProjectウィンドウでInput Actions Assetを選択
- Inspectorで Generate C# Class にチェック
- Class Name(例:
PlayerInputActions)を設定 - 必要に応じてNamespaceを設定
- Apply をクリック
これにより、PlayerInputActions.csが生成され、new PlayerInputActions()でインスタンス化できるようになります。
スクリプトでの実装
方法の使い分け
| 方法 | 適したケース |
|---|---|
| Player Input + Unity Events | 小規模プロジェクト、プロトタイプ、プログラマー以外も設定を変更する場合 |
| C# Class生成 | 中〜大規模プロジェクト、タイプセーフな実装が必要な場合、複雑な入力処理 |
方法1: Player Input + Unity Events
Player Inputコンポーネントを使うと、インスペクターでActionとメソッドを紐づけることができます。
Player Inputコンポーネントの設定
- GameObjectに
Player Inputコンポーネントを追加 ActionsにInput Actions Assetを設定Behaviorを Unity Events に変更Eventsセクションが表示される- 各Actionに対応するメソッドを登録
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerController : MonoBehaviour
{
private Vector2 moveInput;
public void OnMove(InputAction.CallbackContext context)
{
moveInput = context.ReadValue<Vector2>();
}
public void OnJump(InputAction.CallbackContext context)
{
if (context.performed)
{
Debug.Log("ジャンプ!");
}
}
}
方法2: C# Class生成(推奨)
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerController : MonoBehaviour
{
private PlayerInputActions inputActions;
private Vector2 moveInput;
void Awake()
{
inputActions = new PlayerInputActions();
inputActions.Player.Move.performed += OnMove;
inputActions.Player.Move.canceled += OnMove;
inputActions.Player.Jump.performed += OnJump;
}
void OnEnable() => inputActions.Enable();
void OnDisable() => inputActions.Disable();
void OnDestroy()
{
// イベントハンドラの解除(メモリリーク防止)
inputActions.Player.Move.performed -= OnMove;
inputActions.Player.Move.canceled -= OnMove;
inputActions.Player.Jump.performed -= OnJump;
inputActions.Dispose();
}
private void OnMove(InputAction.CallbackContext context)
{
moveInput = context.ReadValue<Vector2>();
}
private void OnJump(InputAction.CallbackContext context)
{
Debug.Log("ジャンプ!");
}
}
メモリリーク防止:
OnDestroyでイベントハンドラを-=で解除し、Dispose()を呼び出すことで、オブジェクト破棄時のメモリリークを防げます。
Action Mapの切り替え
ゲームプレイ中とUI操作中で、有効なAction Mapを切り替えることができます。
public class InputManager : MonoBehaviour
{
private PlayerInputActions inputActions;
void Awake()
{
inputActions = new PlayerInputActions();
}
// ゲームプレイ中:PlayerマップをON、UIマップをOFF
public void EnableGameplayInput()
{
inputActions.Player.Enable();
inputActions.UI.Disable();
}
// UI操作中:UIマップをON、PlayerマップをOFF
public void EnableUIInput()
{
inputActions.Player.Disable();
inputActions.UI.Enable();
}
}
活用例: ポーズメニューを開いたらUIマップに切り替え、閉じたらPlayerマップに戻す。これにより、メニュー操作中にキャラクターが動くことを防げます。
InteractionsとProcessors
Interactions
| Interaction | 用途 |
|---|---|
| Hold | 長押しで発火 |
| Tap | 短いタップを検知 |
| Multi Tap | ダブルクリックなどの連続タップを検知 |
Processors
| Processor | 用途 |
|---|---|
| Normalize | ベクトルを正規化(斜め移動の速度補正) |
| Invert | 入力値を反転 |
| Scale | 入力値をスケーリング(感度調整) |
| Dead Zone | スティックのわずかな傾きを無視 |
デバイスの接続/切断検知
ゲームパッドの抜き差しなど、デバイスの状態変化を検知できます。
using UnityEngine;
using UnityEngine.InputSystem;
public class DeviceManager : MonoBehaviour
{
void OnEnable()
{
InputSystem.onDeviceChange += OnDeviceChange;
}
void OnDisable()
{
InputSystem.onDeviceChange -= OnDeviceChange;
}
void OnDeviceChange(InputDevice device, InputDeviceChange change)
{
switch (change)
{
case InputDeviceChange.Added:
Debug.Log($"デバイス接続: {device.displayName}");
break;
case InputDeviceChange.Removed:
Debug.Log($"デバイス切断: {device.displayName}");
break;
}
}
}
活用例: ゲームパッドが切断されたらポーズ画面を表示する、接続されたら「コントローラーを検出しました」と通知するなど。
よく ある問題とトラブルシューティング
入力が反応しない
OnEnableでinputActions.Enable()を呼び出しているか確認- Action Mapが有効になっているか確認
- Bindingが正しく設定されているか確認
- ビルドに含まれていない場合: Input Actions Assetの設定を確認(下記参照)
Input Actions Assetがビルドに含まれない
Input Actions Assetをビルドに含めるには、以下のいずれかの方法を使用します:
- Player Inputコンポーネントで参照する - GameObjectにアタッチしたPlayer Inputコンポーネントで参照
- スクリプトから参照する -
[SerializeField]でアセットを参照 - Addressablesに登録する - Addressable Assetとして管理
注意: Input System 1.1以前にあった「Preload」チェックボックスは廃止されています(Unity 2021以降)。上記の方法でアセットを参照してください。
移動が止まらない
canceledイベントも登録する:
inputActions.Player.Move.performed += OnMove;
inputActions.Player.Move.canceled += OnMove;
なぜ同じメソッドでいい?:
canceledイベント発火時、context.ReadValue<Vector2>()は自動的にVector2.zeroを返します。そのため、performedとcanceledで同じOnMoveメソッドを使用しても、入力がないときは正しくVector2.zeroが設定されます。
斜め移動が速い
- Composite BindingのModeを「Digital Normalized」に設定
- または「Normalize Vector 2」Processor を追加
まとめ
New Input Systemは、学習コストが高いものの、それに見合う強力な機能を提供します。
- Input Actions でデバイス非依存の入力処理
- Action Map で状況に応じた入力切り替え
- Binding で複数デバイスに同じActionを割り当て
- InteractionsとProcessors で複雑な入力パターンを設定だけで実現
- C# Class生成 でタイプセーフな実装
まずは簡単な移動とジャンプから始めて、徐々に複雑な機能に挑戦してみてください。