【Unity】Unityの入力処理をマスターする - キーボード、マウス、ゲームパッド対応

作成: 2025-12-07最終更新: 2026-07-13

ジャンプが連打される、Input Systemを入れたらInput.GetKeyが例外を吐く——入力処理の定番のつまずきを解決します。GetKeyDown/GetKey/GetKeyUpの使い分け、仮想軸の仕組み、GetAxisとGetAxisRawの違い、新Input Systemへの移行判断までを解説します。

Input.GetKey(KeyCode.Space)でジャンプを書いたら、押している間ずっとジャンプが連打される。直したと思ったら、今度はInput Systemパッケージを入れた途端にInput.GetKeyが例外を吐いて止まる——入力処理は「最初に書くコード」なのに、つまずきポイントが意外と多い場所です。

この記事では、Unityに古くからある標準の Input ManagerInputクラス)を使った入力処理を教科書的に整理します。先に位置づけをはっきりさせておくと、これは 「古いプロジェクトや教材のコードを読み、動かし、いずれ移行するため」のガイド です。いま新規プロジェクトを始めるなら、入口は New Input System入門 をおすすめします。とはいえ世の中のチュートリアルや既存資産の大半は旧Inputで書かれているので、これを読めることは今も必須スキルです。

入力処理のイメージ。キーボード・マウス・ゲームパッドからの信号がゲームキャラクターへ流れ込んでいる

この記事でわかること

  • Unityに2つある入力システムの関係と、この記事の守備範囲
  • GetKeyDown / GetKey / GetKeyUp の正確な使い分け(「瞬間」と「間」)
  • 仮想軸(Virtual Axes)がある理由と GetAxis / GetAxisRaw の違い
  • マウス入力の取得方法
  • 新Input Systemへ移行すべき判断基準

Sponsored

Unityには入力システムが2つある

最初に全体像です。Unityの入力には 2つの仕組みが併存 しています。

旧Input Managerと新Input Systemの比較図。旧はInputクラスをUpdateでポーリングするシンプルな構成、新はInputActionアセットを介したイベントベースの構成
  • Input Manager(旧・標準): Input.GetKey(...)のようにUpdate内で毎フレーム問い合わせる(ポーリング型)。追加インストール不要で、1行から書き始められる
  • Input System(新・パッケージ): 「ジャンプ」「移動」というアクションを定義し、イベントで受け取る。キーコンフィグや複数デバイス対応に強い(New Input System入門 参照)

この記事は前者、Input Manager の教科書です。学習コストが低く、プロトタイプや小規模ゲームでは今でも現役の選択肢です。

補足(定番のハマりポイント): Input Systemパッケージをインストールすると、切り替え確認のダイアログを経て Active Input Handling が「Input System Package (New)」になり、InputクラスがInvalidOperationExceptionを投げるようになります。両方使いたい場合は「Edit > Project Settings > Player > Other Settings > Active Input Handling」を Both に変更してください。「昨日まで動いていた入力が突然例外を吐く」ようになったら、まずここを疑いましょう。

Input Managerの基本:仮想軸という考え方

Input Managerの設定は「Edit > Project Settings > Input Manager」で確認できます。ここにはHorizontalVerticalJumpFire1といった 仮想軸(Virtual Axes) が予め定義されています。

なぜキーを直接読まず、わざわざ「軸」を挟むのか。コードを特定のキーから切り離すためです。

仮想軸の概念図。キーボードのA/Dキー・矢印キー・ゲームパッドのスティックという複数の入力源が「Horizontal」という1つの軸に束ねられ、キャラクターの移動へつながる

例えばHorizontal軸には、a/dキー、左右の矢印キー、そしてゲームパッドのスティックがまとめて割り当てられています。コード側はInput.GetAxis("Horizontal")と書くだけで、どの入力源から来たかを気にせず「左右の入力」として受け取れます。キーボード縛りのコードを書いてしまってから「パッド対応して」と言われて全書き換え——という事故を、この抽象化が防いでくれます。

キーボード入力の取得

キーボード入力はInputクラスの3つのメソッドで取得します。重要なのは「瞬間」と「」の区別です。

GetKeyDown・GetKey・GetKeyUpのタイミング比較図。キーを押して離すまでのタイムライン上で、GetKeyDownは押した瞬間の1フレームだけ、GetKeyは押している間ずっと、GetKeyUpは離した瞬間の1フレームだけ反応する
メソッド反応するタイミング主な用途
Input.GetKeyDown(KeyCode)押された 瞬間 の1フレームだけジャンプ、射撃、決定など単発アクション
Input.GetKey(KeyCode)押されている ずっと溜め、ダッシュ、押しっぱなしの移動
Input.GetKeyUp(KeyCode)離された 瞬間 の1フレームだけ溜め撃ちの解放、長押しの終了

冒頭の「ジャンプが連打される」バグの正体はここです。GetKeyは押している間 毎フレーム trueを返すので、ジャンプに使うと1秒押しただけで数十回発動します。単発アクションは必ずGetKeyDownです。

KeyCodeはキーを定義した列挙型です(例: KeyCode.SpaceKeyCode.WKeyCode.Return)。

using UnityEngine;

public class KeyboardInputExample : MonoBehaviour
{
    void Update()
    {
        // スペースキーが押された瞬間にジャンプ(1回だけ)
        if (Input.GetKeyDown(KeyCode.Space))
        {
            Debug.Log("ジャンプ!");
        }

        // Rキーが押されている間、リロード中
        if (Input.GetKey(KeyCode.R))
        {
            Debug.Log("リロード中...");
        }

        // Escapeキーが離された瞬間にポーズメニューを閉じる
        if (Input.GetKeyUp(KeyCode.Escape))
        {
            Debug.Log("ポーズメニューを閉じる");
        }
    }
}

tips: 入力の検知は必ずUpdateで行います。FixedUpdateは毎フレーム呼ばれるとは限らないため、GetKeyDownのような「1フレームだけtrue」の入力を取りこぼすことがあります。詳しくは UpdateとFixedUpdateの記事 を参照してください。

Sponsored

仮想軸による入力取得

移動のような「方向と強さ」を持つ入力は、仮想軸で受け取ります。似た顔の2つのメソッドがあり、入力値の変化の仕方 が違います。

GetAxisとGetAxisRawの応答の違いの図。GetAxisはキーを押すと-1から1へなだらかな坂のように変化し、GetAxisRawは階段のように即座に-1・0・1へ切り替わる
  • Input.GetAxis(string): -1.0〜1.0の値を スムーズに変化させて 返す。キーボードでも内部で補間がかかり、押した瞬間に0→1へなだらかに立ち上がる。慣性のある滑らかな移動向き
  • Input.GetAxisRaw(string): 補間なしで 即座に -1、0、1を返す。押した瞬間からフルスピードで動く、キビキビした2Dアクション向き

なお、ゲームパッドのスティックの場合はどちらも倒し具合に応じた中間値(0.3や0.7など)が返ります。補間の有無が効くのは主にキーボード入力です。

using UnityEngine;

public class AxisInputExample : MonoBehaviour
{
    public float speed = 10f;

    void Update()
    {
        // "Horizontal"軸(A/Dキー、矢印キー、パッドのスティック)の値を取得
        float horizontalInput = Input.GetAxis("Horizontal");

        // 取得した入力値を使って左右に移動
        transform.Translate(Vector3.right * horizontalInput * speed * Time.deltaTime);
    }
}

「操作がもっさりする」と感じたらGetAxisRawに、「動き出しが唐突すぎる」と感じたらGetAxisに——と、手触りで選び分けるのが実務的です。

マウス入力の取得

マウスのクリックと位置もInputクラスで取得できます。

  • Input.GetMouseButtonDown(int button): ボタンが押された瞬間。0が左、1が右、2が中ボタン
  • Input.GetMouseButton(int button): ボタンが押されている間
  • Input.GetMouseButtonUp(int button): ボタンが離された瞬間
  • Input.mousePosition: カーソルの スクリーン座標(ピクセル単位・左下原点)をVector3で返す。Z座標は常に0
using UnityEngine;

public class MouseInputExample : MonoBehaviour
{
    void Update()
    {
        // 左クリックされたら
        if (Input.GetMouseButtonDown(0))
        {
            // マウスのスクリーン座標を取得
            Vector3 mousePos = Input.mousePosition;
            Debug.Log("左クリック! 座標: " + mousePos);
        }
    }
}

mousePositionは画面上のピクセル座標なので、3D空間の「クリックした先のオブジェクト」を知りたい場合は、この座標からRayを飛ばします。この定番パターンは Physics.Raycastの記事 で詳しく解説しています。

実践:古い2D移動+ジャンプのコードを読んで動かす

仕上げに、古い教材で最もよく見かける「2D移動+ジャンプ」の完成形を、シリーズの方針( 入力はUpdateで読む・物理への適用はFixedUpdateで行う )どおりに組みます。この形が読めれば、世の中の旧Inputのコードはほぼ読めます。

旧Inputによる2D移動+ジャンプの仕組み。A/D/SPACEの入力をUpdateで読み、jumpPressedフラグに貯めて、FixedUpdateで物理に適用する流れ
// ファイル名: LegacyPlayerMove.cs — 旧Input APIの定番形
using UnityEngine;

[RequireComponent(typeof(Rigidbody2D))]
public class LegacyPlayerMove : MonoBehaviour
{
    public float moveSpeed = 6f;
    public float jumpForce = 12f;

    private Rigidbody2D rb;
    private float moveInput;
    private bool jumpPressed;

    void Awake() { rb = GetComponent<Rigidbody2D>(); }

    void Update()
    {
        // 入力はUpdateで読む(GetButtonDownの「1フレームだけtrue」を取りこぼさない)
        moveInput = Input.GetAxisRaw("Horizontal");
        if (Input.GetButtonDown("Jump")) jumpPressed = true; // フラグに貯める
    }

    void FixedUpdate()
    {
        // 物理への適用はFixedUpdateで
        rb.linearVelocity = new Vector2(moveInput * moveSpeed, rb.linearVelocity.y);

        if (jumpPressed)
        {
            jumpPressed = false; // 使ったら必ず消す(貯めっぱなしだと着地後に勝手に跳ぶ)
            rb.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);
        }
    }
}

補足: 古いコードではrb.velocityと書かれていますが、Unity 6ではrb.linearVelocityに改名されています(新旧API読み替えガイド 参照)。また、ジャンプをFixedUpdateで直接GetButtonDownすると取りこぼすため、 Updateで読んでフラグに貯め、FixedUpdateで消費する のがこの形の肝です。

もう1つ、読むときの重要ポイントがあります。"Horizontal""Jump"という文字列は、 そのプロジェクトのProject Settings > Input Managerの設定名 に依存しています。設定側で軸を消したりリネームしたりすると、コードは正しくてもArgumentException: Input Axis Horizontal is not setup.のような実行時エラーになります。「コードだけコピーしたのに動かない」ときは、まずここを見ましょう。

新Input Systemへの読み替え対照表

このコードをいつか新Input Systemへ移行するときは、次の対応で読み替えます(実装手順は New Input System入門 へ)。

旧Input Manager新Input System
Input.GetAxisRaw("Horizontal")Moveアクション(Vector2)のReadValue<Vector2>().x
Input.GetButtonDown("Jump")Jumpアクションのperformedコールバック(またはWasPressedThisFrame()
定義場所: Project Settings > Input Manager定義場所: Input Actionsアセット
デバイス追加=設定の書き足しデバイス追加=Bindingの追加(コード変更なし)

仕上げに、ジャンプを短くタタッと連打してみてください。1回も取りこぼさなければ、「Updateで読んでフラグに貯める」がきちんと働いています。そしてArgumentExceptionが出たときに、コードではなくProject Settingsの設定名へ真っ先に目が行くようになっていれば——世の中の旧Inputコードは、もうあなたの読める言語です。

Sponsored

注意点:Input Managerの引き際

Input Managerはシンプルさが武器ですが、プロジェクトが育つと限界が見えてきます。

  • キーコンフィグが作りにくい: 仮想軸の割り当ては実行時に変更できないため、「キー設定画面」を自作するのはかなり大変です
  • 複数デバイスの本格対応がつらい: キーボード+パッド+タッチを1つのコードで綺麗に扱うには、条件分岐が増え続けます
  • 入力ロジックが散らばる: Updateのポーリングは手軽な反面、入力の定義がコード中に埋まっていきます

こうした要件が出てきたら、イベントベースの 新Input System への移行を検討します。特にキーコンフィグは、新Input Systemなら公式のリバインドAPIで実装できます(キーコンフィグ実装ガイド 参照)。

判断基準は1行です。 「プレイヤーにキー割り当てを変えさせたいか、複数デバイスを本気で対応するか」 ——どちらかがYesになった時が、新Input Systemへの移行タイミングです。逆に言えば、固定キーのPC向け小規模ゲームやプロトタイプなら、Input Managerで最後まで走り切っても何も問題ありません。

おまけ:先に知っておくと良いこと

基本の入力が書けるようになったら、次はこのあたりが視野に入ってきます。

  • 入力とポーズの関係: Time.timeScale = 0のポーズ中でも 入力は止まりません。だからこそポーズ解除の操作を受け付けられます。仕組みは ポーズ実装ガイド で整理しています。
  • UIクリックとの衝突: ボタンの上でクリックしたのにゲーム内の射撃も発動してしまう——という場合は、EventSystem.current.IsPointerOverGameObject()でUI上のポインタを判定して除外するのが定番です。
  • モバイルのタッチ入力: Input.GetMouseButtonDown(0)はタッチでも動作しますが、マルチタッチ(ピンチ操作など)が必要ならInput.touches、本格対応なら新Input Systemの出番です。

まとめ

入力処理は、プレイヤーとゲーム世界を繋ぐ最初のインターフェースです。

  • Unityには 旧Input Managerと新Input Systemの2つ がある。Input Systemパッケージ導入で旧Inputが例外を吐いたら Active Input HandlingをBoth に。
  • GetKeyDownは瞬間、GetKeyは間、GetKeyUpは離した瞬間。単発アクションをGetKeyで書くと連打バグになる。
  • 仮想軸はコードをキーから切り離す仕組みGetAxisはスムーズ、GetAxisRawは即座——手触りで選ぶ。
  • マウスはGetMouseButtonDownmousePosition。3DオブジェクトのクリックはmousePositionからのRaycastで。
  • キーコンフィグか本格マルチデバイス対応が必要になったら、新Input Systemへ移行する。

まずはInput Managerでキャラクターを動かす気持ちよさを体験して、プロジェクトの要件が育ってきたら新Input Systemへ——それが、遠回りに見えて一番堅実なステップアップです。