【Unity】キーボードの入力判定を作り操作できるようにしよう!

Unityでキー入力判定 Unity

こんにちは、ともくんのゲーム作り部屋にようこそ!

このページでは、

「Unityでキー入力をどうやって検知したらいいの?」

「キーボードの入力判定を行う方法を知りたい!」

というお悩みの方に向けた内容となっています。

ゲームでは、キーボードやマウス、コントローラーなどからの入力を検知して、特定の処理を行いゲームが動いていきます。

特に、パソコンでのゲームでは、キーボードの入力を検知することで、キャラクターの移動やジャンプといった操作を行うことが多いです。

Unityでキーボードの入力を検知する場合は、

というメソッドを使うことで、キー入力の判定を行うことができます。

そこで、このページでは、Unityでキーボードからのキー入力判定を行う方法と、実際のスクリプトを紹介していきます。

なお、このページでは、

Windows11
Unity Hub3.11.0
Unity6

のバージョンで解説しています。

この記事を書いた人

ゲーム作りを学び始めた一児のパパです。
このブログは、子供から「ゲームを作ってみたい!」と言われ、非プログラマーでゲーム作りをしたことない僕が、ゲーム作りの本を読んで独学でゲーム開発を学んでいるブログです。
同じように初めてゲーム作りをしている方と一緒に学んでいけるようなブログに出来たらいいなと思っています。
また、「このコードはおかしい」とか「もっと良い書き方があるよ!」などあれば、どんどん指摘して頂けると助かります。

Unityでキーボードの入力判定・検知方法

まずは、Unityでキーボードのキーによる入力や検知する方法をまとめていきます。

冒頭でも紹介した通り、Unityでキー入力を行う場合は、

の3つを使っていきます。

それぞれを分解しながら説明していきます。

Inputクラスのメソッドを使う

Unityでキー入力をする際は、Inputクラスのもつメソッドを使用していきます。

このInputクラスは、キーボードだけでなく、マウスコントローラー、スマホなら画面のタッチなど、様々な入力に対して反応する処理が含まれているクラスになっています。

そのため、キーやボタンなどの入力を感知したいときは、基本的にInputクラスを使用していきます。

なお、クラスとは変数やメソッドをまとめているもののことを呼び、今回はその中の処理を行うメソッドを呼び込むということをしていきます。

キーボードを押した際のメソッドは3つ

Inputクラスでキーボードからの入力を検知するメソッドとして、

  • GetKeyDown
  • GetKey
  • GetKeyUp

の3つのメソッドがあります。

GetKeyDownメソッド:「キーを押した瞬間」を検知

GetKeyDownは、キーを押した瞬間を検知することができるメソッドです。

押した瞬間の1回を検知することになるので、例えばキーを押したらジャンプしたり、攻撃したりなどの際に使用します。

他にも、そのキーを何回押したかという処理でも使うことができるメソッドです。

GetKeyメソッド:「キーを押している間」を検知

GetKeyは、キーを押している間を検知することができるメソッドです。

キーを押している間はずっと検知することが出来るので、キャラクターの移動操作などに特に使われることが多いです。

また、キーを押している間はチャージするといったことにも、使うことができるメソッドです。

GetKeyUpメソッド:「キーを離した瞬間」を検知

GetKeyUpは、キーを離した瞬間を検知することができるメソッドです。

押していたキーを離す瞬間の1回を検知することになるので、単独で使うよりも他のメソッドとともにタイミングを図るのに使うことが多く、例えば弓矢でキーを押している間は弓を引っ張り、キーを離したら矢を放つなどの処理で使うことができます。

他にも、キーを押したらスタートして離したら止まるといったストップウォッチメーターを止めるような使い方でも使えるメソッドです。

メソッドの引数にどのキーにするかをKeyCodeクラスで設定

それぞれのメソッドに、引数を渡してあげることで、どのキーを検知するかを決めることができます。

具体的には、

  • Input.GetKeyDown()
  • Input.GetKey()
  • Input.GetKeyUp()

()部分にどのキーを押すのかを設定していきます。

キーを設定する場合は、KeyCodeクラスを使いそのキーを指定していきます。

例えば、WキーであればKeyCode.Wとなり、Wキーを押している間を検知させるのであれば、

Input.GetKey(KeyCode.W)

と書きます。

他にもよく使用するキーとして、

キー名称KeyCode名
上矢印キーKeyCode.UpArrow
下矢印キーKeyCode.DownArrow
右矢印キーKeyCode.RightArrow
左矢印キーKeyCode.LeftArrow
スペースキーKeyCode.Space
エンターキーKeyCode.Return
左のシフトキーKeyCode.LeftShift
右のシフトキーKeyCode.RightShift
タブキーKeyCode.Tab

などで書いていきます。

if文でtrueを検知して処理を行う

先ほどそれぞれのメソッドに対して、キーを引数に渡しましたが、実際にそのキーが押された場合、メソッドから「true」戻り値として返ってきます。

そこで、if文の条件式に入れてあげることで、そのキーが押された場合の処理を指定していくことができます。

if文は、条件式の中がtrueの場合だけ処理を行うという仕組みになっています。

例えば、Wキーを押している間の処理を書きたいのであれば、

if (Input.GetKey(KeyCode.W))
{
	Wキーを押している間の処理;
}

と書いてあげることで実現できます。

実際にUnityでキー入力判定で処理を入れてみよう

ここからは、実際にUnityでキー入力判定のスクリプトを書いた例を紹介していきます。

なお、スクリプトのアタッチや変数の書き方などの方法については、以下のページでまとめていますので、初心者の方はそちらも参考にしてみてください。

例①WASDキーを使ったキャラクターの移動操作

まずは、キー入力判定で使うことが多い、W・A・S・Dキーを使ったキャラクターの移動操作のスクリプトになります。

スクリプトで書いていくのは、

というキー入力と実行される処理をif文で書いていきます。

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    float playerSpeed = 0.01f;  // プレイヤーの速度を決めている変数

    void Update()
    {
        if (Input.GetKey(KeyCode.W))    // Wキーを押している間
        {
            transform.Translate(0, playerSpeed, 0);     // 上に移動する
        }
        if (Input.GetKey(KeyCode.A))    // Aキーを押している間
        {
            transform.Translate(-playerSpeed, 0, 0);    // 左に移動する
        }
        if (Input.GetKey(KeyCode.S))    // Sキーを押している間
        {
            transform.Translate(0, -playerSpeed, 0);    // 下に移動する
        }
        if (Input.GetKey(KeyCode.D))    // Dキーを押している間
        {
            transform.Translate(playerSpeed, 0, 0);     // 右に移動する
        }
    }
}

押している間を検知するのは、Input.GetKey()のメソッドになるので、このメソッドの引数にどのキーかを設定してあげます。

それをif文の条件式に入れてあげて、それぞれの座標を動かす処理として、transform.Translateを使っています。

それぞれのキーに反応して、キャラクターが移動できているのが分かります。

なお、ここではif文だけで書いているので斜めの移動もできますが、以下のようにif-else文で繋げて書くと、斜め移動を禁止することができます。

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    float playerSpeed = 0.01f;  // プレイヤーの速度を決めている変数

    void Update()
    {
        if (Input.GetKey(KeyCode.W))    // Wキーを押している間
        {
            transform.Translate(0, playerSpeed, 0);     // 上に移動する
        }
        else if (Input.GetKey(KeyCode.A))    // Aキーを押している間
        {
            transform.Translate(-playerSpeed, 0, 0);    // 左に移動する
        }
        else if (Input.GetKey(KeyCode.S))    // Sキーを押している間
        {
            transform.Translate(0, -playerSpeed, 0);    // 下に移動する
        }
        else if (Input.GetKey(KeyCode.D))    // Dキーを押している間
        {
            transform.Translate(playerSpeed, 0, 0);     // 右に移動する
        }
    }
}

例②シフトキーとスペースキーの同時押しによる大ジャンプ

次に、2つのキーを同時押しした際の処理を作ってみます。

スペースキーを押すとジャンプするというゲームはよくありますが、この動きにさらに追加する形で、シフトキーを押しながらスペースキーを押すと、大ジャンプするというものになります。

具体的には、

という2つの処理を行うスクリプトです。

押した瞬間を検知するのは、Input.GetKeyDown()のメソッドになるので、スペースキーは

Input.GetKeyDown(KeyCode.Space)

で検知します。

押している間を検知するのは、Input.GetKey()のメソッドになり、また右と左のどちらのシフトキーを押しても良いとしたいので、

Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)

と、「||」の演算子で繋げて書きます。

なお、今回はRigidbody2Dコンポーネントで、キャラクターに重力を付けているため、AddForceメソッドで力を加えています。

また、ジャンプ中かどうかを検知するために、地面との接地判定を書いています。

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    Rigidbody2D rigid2D;    // Rigidbodyコンポーネントへの参照
    float playerJumpForce = 300.0f; // プレイヤーのジャンプ力の変数
    bool isGrounded = true; // プレイヤーが地面にいるかどうかの変数
    void Start()
    {
        this.rigid2D = GetComponent<Rigidbody2D>(); // Rigidbodyコンポーネントの取得
    }

    void Update()
    {
        if (isGrounded == true &&   // プレイヤーが地面にいる
            Input.GetKeyDown(KeyCode.Space) &&  // スペースキーを押した瞬間
            Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))    // どちらかのシフトキーが押されている間
        {
            this.rigid2D.AddForce(transform.up *  playerJumpForce * 2); // 2倍のジャンプ力でジャンプしている
            isGrounded = false; //  プレイヤーが地面にいない状態に変更
        }
        else if (isGrounded == true &&  // プレイヤーが地面にいる
            Input.GetKeyDown(KeyCode.Space))    // スペースキーを押した瞬間
        {
            this.rigid2D.AddForce(transform.up * playerJumpForce);  // 通常のジャンプ力でジャンプしている
            isGrounded = false; // プレイヤーが地面にいない状態に変更
        }        
    }

    void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.collider.tag == "Ground") // プレイヤーと地面が触れた場合
        {
            isGrounded = true;  // プレイヤーが地面にいる状態に変更
        }
    }
}

まず、15~21行目で、「スペースキーを押す」のと「シフトキーを押している」の2つの条件を満たす大ジャンプの処理を指定しています。

そして、22~27行目で、else ifで繋いで「スペースキーを押す」だけの条件を満たす普通のジャンプの処理を指定しています。

あとは、この処理に対して、接地判定を加えている形になります。

これでスペースキーだけを押した場合は普通のジャンプをして、シフトキーを押しながらスペースキーを押すと大ジャンプするという処理が作れました。

なお以下のように、最初にif文でスペースキーを押す条件を指定して、その後にif-else文でシフトキーを押しているなら大ジャンプ、そうでないなら普通のジャンプという書き方の方がスリムで良いかもしれません。

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    Rigidbody2D rigid2D;    // Rigidbodyコンポーネントへの参照
    float playerJumpForce = 300.0f; // プレイヤーのジャンプ力の変数
    bool isGrounded = true; // プレイヤーが地面にいるかどうかの変数
    void Start()
    {
        this.rigid2D = GetComponent<Rigidbody2D>(); // Rigidbodyコンポーネントの取得
    }

    void Update()
    {
        if (isGrounded == true &&   // プレイヤーが地面にいる
            Input.GetKeyDown(KeyCode.Space))    // スペースキーを押した瞬間
        {
            if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))    // どちらかのシフトキーを押している間
            {
                this.rigid2D.AddForce(transform.up * playerJumpForce * 2); // 2倍のジャンプ力でジャンプしている
            }
            else
            {
                this.rigid2D.AddForce(transform.up * playerJumpForce);  // 通常のジャンプ力でジャンプしている
            }
            isGrounded = false; //  プレイヤーが地面にいない状態に変更
        }
    }

    void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.collider.tag == "Ground") // プレイヤーと地面が触れた場合
        {
            isGrounded = true;  // プレイヤーが地面にいる状態に変更
        }
    }
}

どちらも動きは一緒になると思います。

まとめ

このページでは、Unityでキー入力を判定する方法について、どんな関数を使うのか、書き方や使い方などを紹介していきましたが、いかがでしたでしょうか?

Unityでキーなどの入力を行う場合は、Inputクラスを使って入力を行っていく必要があります。

キー入力には、

の3つのメソッドがあり、それぞれのキー操作に応じた処理を設定していくことができます。

引数にキーを設定してあげることでtrueが戻り値に返ってくるようになるので、if文を使ってキーごとの処理を入力していきます。

ゲームでは、様々な操作があるので、キーの入力判定は覚えておくと便利です。

最後までお読みいただきまして、ありがとうございました!

コメント