unity-input-system について
Unity 6.3 LTS を対象とする開発者向けに、Input System パッケージの API を解説するスキルです。アクション設定や入力の読み取り、デバイスのバインドを扱います。
主な機能
- 01.inputactions のマップ設定
- 02PlayerInput による入力受信
- 03アクションの直接読み取りと有効化
- 04マップ切り替えとイベント処理
- 05Input Debugger での入力確認
活用シーン
- 01移動、ジャンプ、射撃の入力設定
- 02キーボード、ゲームパッド、タッチ入力の統合
- 03ゲームプレイと UI 間の入力マップ切り替え
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ gamedev-skills/ awesome-gamedev-agent-skills --skill unity-input-systemインストール後、Claude Code で/unity-input-systemを入力して読み込まれたか確認します。
同梱ファイルreferences/rebinding.md
詳細
Unity Input System(新)
Unity の Input System パッケージ(com.unity.inputsystem、1.x)を使って入力を読み取ります。アクションベースで、デバイスに依存せず、再バインド可能です。対象は Unity 6.3 LTS です。従来の Input.GetAxis/Input.GetKey Input Manager に代わる最新のシステムです。
使用する場面
- 移動/ジャンプ/射撃の入力を設定するとき、アクションマップとコントロールスキームを含む
.inputactionsアセットを定義するとき、PlayerInputコンポーネントを接続するとき、Vector2のスティック/WASD 値を読み取るとき、またはゲームパッド+キーボード+タッチを一組のアクションで扱うときに使用します。 Packages/manifest.jsonにcom.unity.inputsystemが含まれている場合、またはプロジェクトに*.inputactionsアセットがある場合に使用します。
使用しない場面: エンジンをまたいだ再バインド可能な操作の設計には、input-systems を使用します(このスキルは Unity 固有の API です)。入力ベクトルを取得した後のキャラクター移動には、unity-physics/unity-csharp-scripting を使用します。
基本的なワークフロー
- Active Input Handling を確認します(Project Settings → Player)。パッケージが入力を受け取るのは、この設定が
Input System Package (New)またはBothの場合のみです。古いInput.GetAxisコードが残っている場合は、Bothが必要です。 .inputactionsアセットを作成します。 アクションマップ(例:Gameplay)を追加し、アクション(Move= Value/Vector2、Jump= Button、Fire= Button)を追加して、コントロールと複合バインディング(WASD = 2D Vector composite)にバインドします。- 入力の読み取り方法を選択します。
PlayerInputコンポーネント(デザイナー向け)— プレイヤーに追加してアセットを指定し、Behavior(Send Messages / Broadcast / Invoke Unity Events / Invoke C# Events)を選択します。1 人またはローカル協力プレイのプレイヤーに最適です。- コードから直接読み取る(
InputActionReference/InputActionAsset)— 最も細かく制御できます。アクションをEnable()して読み取ります。システムやツールに最適です。
- 読み取るアクション/マップを有効にします。
PlayerInputはデフォルトのマップを自動的に有効にします。自分で参照するアクションは.Enable()する必要があります(終了時には無効にします)。 - すべてのハンドラーで条件分岐する代わりに、状況に応じてアクションマップを切り替えます(gameplay ↔ UI/menu)。
- Input Debugger(Window → Analysis → Input Debugger)でデバイスとアクションの発火を確認します。
パターン
1. PlayerInput の「Send Messages」(同じ GameObject 上のハンドラー)
using UnityEngine;
using UnityEngine.InputSystem;
// PlayerInput (Behavior = Send Messages) calls On<ActionName>(InputValue) by name.
public class PlayerInputReceiver : MonoBehaviour
{
private Vector2 _move;
private void OnMove(InputValue value) => _move = value.Get<Vector2>(); // Move action
private void OnJump(InputValue value) { if (value.isPressed) Jump(); } // Button action
private void Update() { /* drive movement from _move */ }
private void Jump() { }
}
2. コードからアクションを直接読み取る(値のポーリング)
using UnityEngine;
using UnityEngine.InputSystem;
public class DirectMover : MonoBehaviour
{
[SerializeField] private InputActionReference moveAction; // assign the Move action
private void OnEnable() => moveAction.action.Enable(); // REQUIRED or it reads zero
private void OnDisable() => moveAction.action.Disable();
private void Update()
{
Vector2 move = moveAction.action.ReadValue<Vector2>(); // continuous value
transform.Translate(new Vector3(move.x, 0, move.y) * (5f * Time.deltaTime));
}
}
3. イベントコールバック+アクションマップの切り替え(gameplay ↔ UI)
[SerializeField] private InputActionAsset actions;
private void OnEnable()
{
actions.FindAction("Gameplay/Fire").performed += OnFire; // edge event: fires once
actions.FindActionMap("Gameplay").Enable();
}
private void OnDisable() => actions.FindAction("Gameplay/Fire").performed -= OnFire;
private void OnFire(InputAction.CallbackContext ctx) => Shoot(); // ctx.ReadValue<T>() if needed
private void OpenPauseMenu() // change context, don't sprinkle if-checks
{
actions.FindActionMap("Gameplay").Disable();
actions.FindActionMap("UI").Enable();
}
private void Shoot() { }
注意点
- 入力がまったくない → Active Input Handling がまだ
Input Manager (Old)になっているか、アクション/マップをEnable()し忘れています。PlayerInputは自動的に有効にしますが、生のInputActions は有効にしません。 - 古い入力バックエンドに関する
InvalidOperationExceptionが発生する → Active Input Handling がNewのときに、いずれかのスクリプトがまだInput.GetAxis/Input.GetKeyを呼び出しています。コードを移行するか、Bothに設定します。 ReadValueでボタンが 0 として読み取られる → ボタンの押下はエッジイベントです。トリガーに対してフレームごとにReadValueを使うのではなく、performedコールバック(またはWasPressedThisFrame())を使用します。Send Messagesのハンドラーがまったく呼び出されない → 受信側のスクリプトはPlayerInputと同じ GameObject 上に置く必要があります。Broadcast Messagesなら子オブジェクトにも届きます。- サブスクリプションが解除されずに残る →
OnDisableで購読を解除します(-=)。購読を解除せずにOnEnableで再購読すると、ハンドラーが重複します。 - タッチ/ゲームパッドが検出されない → 対応するコントロールスキームを有効にして、Input Debugger でデバイスを確認します。Vector2 複合バインディングには、4 つすべてのバインディング設定が必要です。
参考資料
- インタラクティブな操作の再バインド(
PerformInteractiveRebinding)、バインディングの JSON 形式での保存/読み込み、PlayerInputManagerを使ったローカルマルチプレイヤーについては、references/rebinding.mdを参照してください。 - 主なドキュメント:Unity Manual「Input System」
(
https://docs.unity3d.com/Manual/com.unity.inputsystem.html)。
関連スキル
input-systems— エンジンに依存しない入力アーキテクチャ(再割り当て、バッファリング、複数デバイス)。unity-csharp-scripting— これらのハンドラーが配置される MonoBehaviour。unity-physics— 入力ベクトルを Rigidbody に適用する方法。
コメント
Markdown 対応