mcpField
U
unity-input

unity-input

github.com/nice-wolf-studio開発4075 回インストール6 週間前に更新
リポジトリ

unity-input について

unity-input は、Unity 開発者向けに Input System のアクションベースの設定と入力取得を解説するガイドです。旧 Input Manager との違いを踏まえ、複数デバイス、ローカルマルチプレイヤー、タッチ、実行時の再バインドを扱います。

主な機能

  1. 01InputAction と Action Map
  2. 02PlayerInput によるローカルマルチプレイヤー管理
  3. 03ポーリングとイベント駆動の入力取得
  4. 04キーボード、ゲームパッド、マウス、タッチ
  5. 05入力インタラクションとプロセッサー
  6. 06実行時の再バインドとデバイス検出

活用シーン

  1. 01複数デバイスに対応する操作設定
  2. 02ゲームプレイと UI の Action Map 切り替え
  3. 03ローカルマルチプレイヤーのデバイス割り当て
  4. 04実行時の操作再バインドの追加

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/nice-wolf-studio/unity-claude-skills --skill unity-input

インストール後、Claude Code で/unity-inputを入力して読み込まれたか確認します。

同梱ファイルreferences/input-system-api.md

詳細

Unity Input System

Input System の概要:新旧の比較

Unity には、2 つの入力システムがあります。

機能新しい Input System(推奨)レガシー Input Manager
パッケージcom.unity.inputsystem(Unity 6.3 向け v1.19.0)組み込み(UnityEngine.Input)
アーキテクチャアクションベース、イベント駆動ポーリングベース
デバイスのサポートゲームパッド、キーボード、マウス、タッチ、XR、カスタムキーボード、マウス、ジョイスティック
マルチプレイヤーPlayerInput によるローカルマルチプレイヤー機能を内蔵手動で実装
再バインド実行時の再バインドに対応非対応
クロスプラットフォームデバイスタイプごとのコントロールスキームプラットフォームごとに手動でコードを作成

新しい Input System は、Package Manager からインストールするパッケージです。従来の Input.GetKey/Input.GetAxis API を、入力の目的とデバイスのコントロールを分離するアクションベースのモデルに置き換えます。

名前空間: UnityEngine.InputSystem

クイックスタートの設定

1. パッケージをインストールする

Window > Package Manager > Unity Registry > Input System からインストールします。

2. プロジェクト全体で使用するデフォルトのアクションを作成する

Edit > Project Settings > Input System Package > Input Actions に移動し、「Create and assign a default project-wide Action Asset」 をクリックします。

次のデフォルトのアクションマップが作成されます。

  • Player:Move、Look、Jump、Attack
  • UI:Navigate、Submit、Cancel

各アクションには、キーボード、ゲームパッド、XR コントローラー、タッチスクリーン向けのバインディングが含まれています。

3. スクリプトで入力を読み取る
using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerController : MonoBehaviour
{
    InputAction moveAction;
    InputAction jumpAction;

    void Start()
    {
        moveAction = InputSystem.actions.FindAction("Move");
        jumpAction = InputSystem.actions.FindAction("Jump");
    }

    void Update()
    {
        Vector2 moveValue = moveAction.ReadValue<Vector2>();
        transform.Translate(new Vector3(moveValue.x, 0, moveValue.y) * Time.deltaTime * 5f);

        if (jumpAction.IsPressed())
        {
            // Jump logic
        }
    }
}

複数のマップで同じ名前のアクションを使用する場合は、"Player/Move" のように両方を指定します。

Input Actions と Action Maps

基本概念
  • InputAction:コントロール値を返す、またはコールバックを呼び出す名前付きアクション
  • InputActionMap:関連するアクション(「Player」、「UI」、「Vehicle」など)をまとめた名前付きコレクション
  • InputBinding:アクションとデバイスコントロールの関係
  • InputSystem.actions:プロジェクト全体で使用するアクションへの参照
アクションの作成

方法 1 — Input Actions Editor(推奨): Project Settings > Input System Package から設定します。

方法 2 — MonoBehaviour のフィールド: スクリプトで InputAction フィールドを直接宣言します(Inspector で設定可能)。

方法 3 — コード:

var moveAction = new InputAction("Move", InputActionType.Value);
moveAction.AddCompositeBinding("Dpad")
    .With("Up", "<Keyboard>/w").With("Down", "<Keyboard>/s")
    .With("Left", "<Keyboard>/a").With("Right", "<Keyboard>/d");
moveAction.Enable();

方法 4 — JSON: var map = InputActionMap.FromJson(jsonString);

アクションのライフサイクル

アクションは無効の状態で開始します。入力に応答させるには、.Enable() を呼び出す必要があります。有効な状態ではバインディングを変更できないため、先に .Disable() を呼び出してください。

Input Action アセット(.inputactions)

アクション、バインディング、コントロールスキームを保存する JSON ファイルです。Assets > Create > Input Actions から作成します。

C# クラスの自動生成: アセットのインポーターで「Generate C# Class」を有効にすると、型安全にアクセスできます。

public class MyPlayerScript : MonoBehaviour, IGameplayActions
{
    MyPlayerControls controls;

    public void OnEnable()
    {
        controls = new MyPlayerControls();
        controls.gameplay.SetCallbacks(this);
        controls.gameplay.Enable();
    }

    public void OnDisable()
    {
        controls.gameplay.Disable();
    }

    public void OnMove(InputAction.CallbackContext context)
    {
        Vector2 move = context.ReadValue<Vector2>();
        // Handle movement
    }
}

PlayerInput コンポーネント

PlayerInput コンポーネントは Input Actions をスクリプトのメソッドにマッピングし、デバイスフィルタリングと画面分割によるローカルマルチプレイヤーを処理します。

設定
  1. プレイヤーの GameObject に PlayerInput コンポーネントを追加します
  2. Actions フィールドに Action Asset を割り当てます
  3. Default Action Map を選択します
  4. 通知タイプの Behavior を選択します
Behavior のオプション
Behavior仕組み適した用途
Send MessagesGameObject.SendMessage()簡単なプロトタイピング
Broadcast Messages階層内に BroadcastMessage() を送信コンポーネント階層
Invoke Unity EventsInspector で設定するイベントルーティングデザイナー向けの接続
Invoke C# EventsonActionTriggered、onDeviceLost、onDeviceRegainedプログラマーによる制御
Send Messages パターン
public class PlayerActions : MonoBehaviour
{
    public void OnJump()
    {
        // Called when Jump action triggers (no parameters)
    }

    public void OnMove(InputValue value)
    {
        Vector2 v = value.Get<Vector2>();
        // InputValue is only valid during this callback
    }
}
Unity Events パターン
public void OnFire(InputAction.CallbackContext context)
{
    if (context.performed)
    {
        // Fire logic
    }
}
PlayerInput の管理
PlayerInput playerInput = GetComponent<PlayerInput>();
playerInput.DeactivateInput();                      // Disable all input
playerInput.ActivateInput();                         // Re-enable with default map
playerInput.SwitchCurrentActionMap("Vehicle");       // Switch action map

コードで入力を読み取る

ポーリング(Update 内)
// 2D movement axis
Vector2 move = moveAction.ReadValue<Vector2>();

// Button state
if (jumpAction.IsPressed()) { /* held down */ }
if (jumpAction.WasPressedThisFrame()) { /* just pressed */ }
if (jumpAction.WasReleasedThisFrame()) { /* just released */ }
コールバック(イベント駆動)
void OnEnable()
{
    fireAction.started += OnFireStarted;
    fireAction.performed += OnFirePerformed;
    fireAction.canceled += OnFireCanceled;
    fireAction.Enable();
}

void OnDisable()
{
    fireAction.started -= OnFireStarted;
    fireAction.performed -= OnFirePerformed;
    fireAction.canceled -= OnFireCanceled;
    fireAction.Disable();
}

void OnFireStarted(InputAction.CallbackContext ctx) { /* Input began */ }
void OnFirePerformed(InputAction.CallbackContext ctx) { /* Completed */ }
void OnFireCanceled(InputAction.CallbackContext ctx) { /* Interrupted */ }

ゲームパッド/キーボード/マウス/タッチ

ゲームパッド
using UnityEngine.InputSystem;

// Current gamepad (null if none connected)
var gp = Gamepad.current;
if (gp == null) return;

Vector2 leftStick = gp.leftStick.ReadValue();
bool southPressed = gp.buttonSouth.isPressed;

// Access by enum
gp[GamepadButton.LeftShoulder].isPressed;
gp[GamepadButton.Y].isPressed;          // Xbox style
gp[GamepadButton.Triangle].isPressed;   // PlayStation style

// Rumble / Haptics
gp.SetMotorSpeeds(0.25f, 0.75f); // low-frequency, high-frequency
gp.ResetHaptics();

// Global haptics control
InputSystem.PauseHaptics();
InputSystem.ResumeHaptics();
InputSystem.ResetHaptics();

対応するゲームパッド:DualShock 3/4、DualSense、Xbox(XInput/Bluetooth)、Switch Pro。汎用 HID ゲームパッドは Gamepad デバイスではなく、汎用ジョイスティックとして認識されます。

キーボードとマウス
var kb = Keyboard.current;
if (kb.spaceKey.wasPressedThisFrame) { /* space pressed */ }

var mouse = Mouse.current;
Vector2 mousePos = mouse.position.ReadValue();
float scroll = mouse.scroll.ReadValue().y;
bool leftClick = mouse.leftButton.isPressed;
タッチ

API レベルは 2 つあります。

低レベル — タッチスクリーンデバイス:

var ts = Touchscreen.current;
if (ts.primaryTouch.press.isPressed)
{
    Vector2 pos = ts.primaryTouch.position.ReadValue();
}

高レベル — EnhancedTouch API:

using UnityEngine.InputSystem.EnhancedTouch;

void OnEnable() => EnhancedTouchSupport.Enable();
void OnDisable() => EnhancedTouchSupport.Disable();

void Update()
{
    foreach (var touch in Touch.activeTouches)
    {
        Debug.Log($"{touch.touchId}: {touch.screenPosition}, {touch.phase}");
    }
}

タッチフェーズ:Began、Moved、Stationary、Ended、Cancelled。

Actions によるマルチタッチ: <Touchscreen>/touch*/press をバインドし、アクションタイプを PassThrough に設定すると、タッチごとのコールバックを受け取れます。

タッチシミュレーション: 開発中にマウス/ペンからのタッチをシミュレートするには、TouchSimulation.Enable() で有効にします。

デバイスの検出
// Monitor device connections
InputSystem.onDeviceChange += (device, change) =>
{
    if (change == InputDeviceChange.Added)
        Debug.Log($"Device connected: {device.displayName}");
};

インタラクションとプロセッサー

インタラクションは、アクションフェーズを駆動する入力パターンを定義します。

インタラクションフェーズ
フェーズ意味
Waiting入力待ち
Started入力を受け取りましたが、まだ完了していません
Performedインタラクションが完了しました — 主な応答のトリガー
Canceledインタラクションが中断されました
組み込みインタラクション
インタラクション説明主なパラメーター
Default自動適用されます。動作はアクションタイプによって異なります—
Press明示的なボタン押下の動作pressPoint、behavior(PressOnly/ReleaseOnly/PressAndRelease)
Hold最小時間にわたって押し続けますduration、pressPoint
Tap素早く押して離しますduration、pressPoint
SlowTap押し続けてから離しますduration、pressPoint
MultiTapタップを繰り返すシーケンスtapTime、tapDelay、tapCount、pressPoint
コードでインタラクションを追加する
var action = new InputAction("fire");
action.AddBinding("<Gamepad>/buttonSouth")
    .WithInteractions("tap(duration=0.8)");
タップと長押しの例(発射とチャージ)
var fireAction = new InputAction("fire");
fireAction.AddBinding("<Gamepad>/buttonSouth").WithInteractions("tap,slowTap");
fireAction.started += ctx => { if (ctx.interaction is SlowTapInteraction) ShowChargingUI(); };
fireAction.performed += ctx => {
    if (ctx.interaction is SlowTapInteraction) ChargedFire(); else Fire();
};
fireAction.canceled += _ => HideChargingUI();
fireAction.Enable();
カスタムインタラクション

IInputInteraction を実装し、InputSystem.RegisterInteraction<T>() で登録します。完全な例については、references/input-system-api.md を参照してください。

よくあるパターン

アクションマップの切り替え(例:ゲームプレイと UI)
public class GameStateManager : MonoBehaviour
{
    PlayerInput playerInput;

    void Start() => playerInput = GetComponent<PlayerInput>();

    public void EnterMenu() => playerInput.SwitchCurrentActionMap("UI");
    public void ExitMenu() => playerInput.SwitchCurrentActionMap("Player");
}
実行時の再バインド
var rebindOp = action.PerformInteractiveRebinding()
    .WithControlsExcluding("Mouse")
    .OnMatchWaitForAnother(0.1f)
    .OnComplete(op =>
    {
        Debug.Log($"Rebound to: {op.action.bindings[0].effectivePath}");
        op.Dispose();
    })
    .Start();
同じアクションに複数のバインディングを設定する(WASD + 矢印キー)
var moveAction = new InputAction("Move", InputActionType.Value);
moveAction.AddCompositeBinding("2DVector")
    .With("Up", "<Keyboard>/w").With("Down", "<Keyboard>/s")
    .With("Left", "<Keyboard>/a").With("Right", "<Keyboard>/d");
moveAction.AddCompositeBinding("2DVector")
    .With("Up", "<Keyboard>/upArrow").With("Down", "<Keyboard>/downArrow")
    .With("Left", "<Keyboard>/leftArrow").With("Right", "<Keyboard>/rightArrow");

アンチパターン

アンチパターン問題正しい方法
Input.GetKey()(旧式)を使用する新しい Input System と互換性がなく、再バインドや複数デバイスに対応できませんバインディングを設定した InputAction を使用します
.Enable() を呼び出さずにアクションを読み取るアクションは無効な状態で開始するため、値を返しませんOnEnable() で必ず action.Enable() を呼び出します
クリーンアップ時に .Disable() を忘れるメモリリークや予期しないコールバックが発生しますOnDisable() で action.Disable() を呼び出します
アクションが有効な状態でバインディングを変更する例外がスローされます変更前に .Disable() を呼び出し、その後 .Enable() を呼び出します
ゲームプレイコードにデバイスパスをハードコードするクロスプラットフォーム対応が損なわれます代わりに Actions + Control Schemes を使用します
コールバックの外で InputValue を使用する値が有効なのはコールバックのフレーム中のみです値をすぐにフィールドへコピーします
null チェックなしで Gamepad.current にアクセスするゲームパッドが接続されていない場合、クラッシュします必ず if (Gamepad.current == null) return; で確認します
アクションのコールバックを登録解除しないシーンの再読み込み時にエラーが発生しますOnDisable() で登録を解除します
本番環境で SendMessages の動作を使用するリフレクションによるパフォーマンス上のオーバーヘッドが発生しますInvoke Unity Events または Invoke C# Events を使用します
EnhancedTouch を有効にせずにポーリングする空のコレクションが返されます先に EnhancedTouchSupport.Enable() を呼び出します

主要な API クイックリファレンス

API用途
InputSystem.actionsプロジェクト全体のアクション
InputSystem.actions.FindAction("name")名前でアクションを検索
action.ReadValue<T>()現在の値を読み取る
action.IsPressed()ボタンが押されているか確認
action.WasPressedThisFrame()ボタンがこのフレームで押されたか確認
action.WasReleasedThisFrame()ボタンがこのフレームで離されたか確認
action.Enable() / action.Disable()有効化/無効化
action.started / performed / canceledコールバックイベント
action.AddBinding("path")コードでバインディングを追加
action.AddCompositeBinding("type")コンポジット(Dpad、2DVector)を追加
.WithInteractions("tap(duration=0.5)")バインディングにインタラクションを追加
Gamepad.current現在のゲームパッドへの参照
Keyboard.current / Mouse.current現在のキーボード/マウス
Touchscreen.current現在のタッチスクリーン
EnhancedTouchSupport.Enable()拡張タッチ API を有効化
Touch.activeTouchesすべてのアクティブなタッチ(拡張)
InputSystem.onDeviceChangeデバイス接続イベント
PlayerInput.SwitchCurrentActionMap()アクティブなアクションマップを変更
action.PerformInteractiveRebinding()実行時のリバインドを開始

関連するスキル

  • unity-scripting — MonoBehaviour のライフサイクル、C# のパターン
  • unity-ui — UI Toolkit の入力統合、InputSystemUIInputModule
  • unity-xr — XR コントローラー入力、トラッキング対象デバイス

追加リソース

コメント