【中級者向けUnity講座】RPG編 part2 『プレイヤーからの入力を受け取る』


はじめに

皆様こんにちは。
個人でゲーム制作をしております、kenと申します。
この講座では、実際にゲームを作りながら「こういう事をするなら、こういう風にすると良いと思うよ。詳しくは自分で調べてね。」という感じで、ゲームの作り方、Unityの機能やアセット等を軽く紹介して行きます。

今回は、前回の続きで、入力を受け取る方法をいくつか紹介します。

Inputクラスでキー入力の入力状態を取得する

キー入力を受け取りたい場合の一番簡単なやり方は、以下のようなコードで入力の状態を取得しIf文で分岐させる事かと思います。

void Update() {
    if(Input.GetButtonDown("cancel")) {
        //cancelボタンが押された時の処理
    }
}

詳しくは以下の記事が非常にわかりやすいです。
Unityのキー入力まとめ ~Inputクラス~

このときの注意点ですが、キーの入力状態の更新はUpdateの際に行われるので、FixedUpdate内だとキーの入力状態が正しく取得できません。
昔はUnity公式のスクリプトでもFixedUpdate内にキー入力の処理が書かれていたりしたこともあって、ネット上にもFixedUpdate内にキー入力を書いている記事が結構あるので注意です。

UpdateとFixedUpdateの使い分け方は以下の記事が分かりやすいです。
UpdateとFixedUpdateの使い分け

どうしてもFixedUpdate内でキー入力を取得したい場合は、以下のコードのようにWaitForFixedUpdateを使ってFixedUpdateが呼び出されるまでキーの入力状態を保持するようなクラスを作るなどすれば、できない事はないです。

public class FixedUpdateInput {

    bool fire1 = false;
    bool fire1Up = false;
    bool fire1Down = false;

    void Update() {
        if (Input.GetButton("Fire1")) {
            if (!fire1) fire1Down = true;
            fire1 = true;
        } else {
            if (fire1) fire1Up = true;
            fire1 = false;
        }
        StartCoroutine(Refresh());
    }

    IEnumerator Refresh() {
        yield return new WaitForFixedUpdate();
        fire1Up = false;
        fire1Down = false;
    }
    public bool GetFire1() { return fire1; }
    public bool GetFire1Down() { return fire1Down; }
    public bool GetFire1Up() { return fire1Up; }
}

また、キーが押されている間移動し続けるような処理を書く場合は更に、フレームレートの変動にも注意が必要です。
例えば、1フレームに1進む処理を書いた場合、30FPSの時は1秒間に30進みますが60FPSの時には1秒間に60進むので、フレームレートによって移動速度が変わってしまいます。
これを回避したい場合は、以下の記事を参考にTime.deltaTimeを使って1フレームの移動量を調節しましょう。
【Unity】「Time.deltaTime」を使わないといけない理由を説明する

他には、フレームレートを固定するという手もありますね。
UnityでFPSを設定する方法
Unity で正確なフレームレートを実現する

OnMouse関数を使う

StartやUpdateのようにMonoBehaviourを継承していれば自動で呼び出される関数の中にマウスの入力によって呼び出されるものがあります。
以下は公式リファレンスからの引用です。

関数名 説明
OnMouseDown OnMouseDown is called when the user has pressed the mouse button while over the GUIElement or Collider.
OnMouseDrag OnMouseDrag はユーザーが GUIElement または Collider をマウスでクリックし、ドラッグしている間呼び出されます。
OnMouseEnter OnMouseEnter は GUIElement または Collider 上にマウスが乗ったときに呼び出されます
OnMouseExit OnMouseExit は GUIElement または Collider 上からマウス離れたときに呼び出されます
OnMouseOver OnMouseOver は GUIElement または Collider 上にマウスがあり続ける限り毎フレーム呼び出され続けます
OnMouseUp OnMouseUp はユーザーがマウスボタンを離したときに呼び出されます
OnMouseUpAsButton OnMouseUpAsButton はマウスを押した時と同じ GUIElement や Collider 上でマウスを離した時のみに呼び出されます。

uGUIのButtonを使う

UnityのButtonの基本的な使い方は以下です。
【Unity uGUI】ボタン(Button)の基本的な使い方を徹底解説!

上の記事にもあるように、ボタンが押された時の処理を書いたスクリプトを用意して、それをInspecterでOnClickに登録するのが基本的な使い方になりますが、このOnClickへの登録は以下のようなコードでスクリプトから行うこともできます

public class AddListenerTest : MonoBehaviour {

    private Button button;

    void Start () {
        button= GetComponent <Button>();
        button.onClick.AddListener (OnClickButton);
    }

    public void OnClickButton() {
        // ボタンが押された時の処理
    }
}

詳しくは以下の記事が分かりやすいです。
Unityでスクリプトからボタンのイベントリスナーを取り付ける

Event Triggerコンポーネントを使う

uGUIでマウスのドラッグやマウスポインターがボタンの上にあるかどうかなど、クリック以外の操作を受け取りたい場合はEvent Triggerコンポーネントが使えます。
以下の記事が分かりやすいです。
【Unity】Event Triggerの種類と用途と使い方【保存版】

マウスイベントのインタフェースを実装する

Event Triggerコンポーネントを使うのと同じようなことをスクリプトだけでやることもできます。
やり方は以下の記事が分かりやすいです。自作のボタンを作りたい時なんかに便利です。
Unityでマウスイベントのインタフェースの実装とレイキャスト

新しいInput Systemを使う

Unityでは現在、従来のInput Systemの問題点を解決した、新しいInput Systemが開発されています。2020/02/29現在はまだプレビュー版ですが、今後はこちらがスタンダードになると思われます。

使い方は以下の記事が分かりやすいです。
【Unity】新・新しいInput Systemの使い方(Inputsystem ver 1.0版)

まとめ

一つ一つは簡単ですが、いろんなやり方があって結構奥が深いです。
今週はここまでにして、次回はちょっと上級者向けの、プレイヤーからの入力を待つ方法を紹介したいと思います。

次回→【中級者向けUnity講座】RPG編 part3 『入力を待つ』