原カバンは鞄のお店ではありません。

Unityを使ったゲーム制作のあれこれを綴っていきます。

【Unity】キーボード(+ゲームパッド)のみでuGUIを操作したい

酷暑

日中に小一時間出かけるだけで今日のターンは終了した気分になる夏バテ気味な皆さんこんにちは。先日は例のジブリ映画を観に出掛け、映画館までの往復計一時間で全ての体力を使い果たしました。映画自体は「全く説明のない"千と千尋"」みたいな感じで、各要所毎のシーンは面白く飽きずに観れたのですが、鑑賞後に全体を振り返ると特に印象に残る場面がない、というなんとも不思議な映画でした。あと、「このキャラクターの声、ちょっと浮いてるな」と思ったらそれが菅田将暉でビックリ。あんな作りこんだ声で演技させるなら普通に声優使えばいいのに。

 

ゲームパッド対応

自作のアドベンチャーゲーム「W.T.」は既にアーリーアクセス版をSteamでリリースしていますが、東京ゲームダンジョン3での出展前にリリースしておきたい&東京ゲームダンジョン3に出展する試遊版を制作する必要があった事もあり、現状ではゲームパッドでの操作には対応していません

store.steampowered.com

とはいえ、最近ではPCゲームでもゲームパッドで操作するのが主流となっているので、現在はその対応中なのですが、ネックとなっているのは、uGUIに対してゲームパッドでどう操作するか、という事。
Unityではメニュー画面、オプション画面等を作成するために必要なButtonやTextBoxなどのUI(uGUI)が提供されているのですが、WindowsフォームやJavaScriptなどのWeb画面とは違い、フォーカスという概念がないので、マウス操作以外のゲームパッドやキーボードでのキー操作に対応してフォーカスを移動させるにはEventSystemを使ってちょっと工夫が必要です。

 

EventSystem

UnityでのUI操作は、EventSystemというコンポーネントを必ず使用します
このEventSystemではどのオブジェクト(UI)が現在アクティブなのか、どのオブジェクト(UI)が『選択中』なのかという事が管理されています。

例えば下の図のようなメニュー画面でマウス操作ではなくキーボード操作でボタンを選択したい場合を想定します。

この時、ゲーム開始直後に最初に選択されるボタンの設定はEventSystemの「First Selected」という項目で設定することができます。

この項目に起動時、選択状態にしておきたいゲームオブジェクト(ボタン)を指定しておくと

ゲーム起動時に選択状態となります。(上の動画では選択状態は青くなるようにHighlightedColorを設定しています)

 

キーボード操作によるボタンの選択

最初に選択したいボタンは上記の設定にて実現することができますが、そこからキーボード操作で「選択状態」のボタンを移動させたい場合、Standalone Input Moduleというコンポーネントを使用します。

このStandalone Input Moduleでは横方向の入力(Horizontal Axis)と縦方向の入力(Vertical Axis)および決定ボタン(Submit Button)等の動作と、InputManager(UnityメニューのEdit→Project Settingから設定)で定義されている入力方法との紐づけが行われています。

Input Managerのウィンドウ

このInputManagerに関してはUnityのマニュアルを参照してください。

docs.unity3d.com

この設定はデフォルトならキーボードの矢印キーとゲームパッドの左スティックが設定されているので、通常なら特に意識することなく矢印キーと左スティックで選択状態のボタンを移動させることができます

 

また、一部のボタンを非表示化(非アクティブ化)しても問題なく移動させる事もできます。

 

…と、ここまでなら特に工夫も必要なくキー操作対応が行えそうですが、InputManagerに定義された入力以外の操作でボタンの選択を行い場合、例えばTabキーで「選択状態」のボタンを移動させたい場合はStandalone Input Moduleの設定だけでは対応することができません

 

方向入力以外によるボタン選択

方向入力による操作は継続しつつ、その他のキーでもボタン選択の操作を行いたい場合には、自力でスクリプト組む必要があります。
具体的にはそのキー(例えばTabキー)のキー押下(GetKeyDown)をUpdateで検知した場合、

  1. 現在「選択状態」となっているオブジェクト(ボタン)をEventSystemから取得する
  2. 「選択状態」ボタンの親クラスSelectableから、次のボタン(右、もしくは下)のボタンを取得する
  3. 次ボタンをEventSystemに渡して「選択状態」にする

という手順を行います。

void Update()
{
    // Tabキー押下
    if (Input.GetKeyDown(KeyCode.Tab))
    {
        // 選択中のオブジェクト取得
        GameObject nowObj = EventSystem.current.currentSelectedGameObject;

        // Selectableがある場合
        if(nowObj.TryGetComponent<Selectable>(out var sr))
        {
            // Selectableを取得
            Selectable mySelectable = sr;
            
            // 一つ下のオブジェクトを選択
            EventSystem.current.SetSelectedGameObject(mySelectable.navigation.selectOnDown.gameObject);
        }

    }
}

上のスクリプトを実行すると

Tabキーによってボタンを選択することができます。

 

ゲームパッド対応には道半ば

前述のようにUnityのuGUIではフォーカスという概念がないので、Standalone Input Moduleの設定だけは中途半端な動作になります。
特にマウス操作と併用された場合、「選択状態」となるオブジェクトはボタンだけとは限らないので、ボタンやスティックを操作しても何の反応もしない、という状態に陥る事が多いです。
例えば、ボタンが選択されている状態でボタン以外の箇所をマウスでクリックされた場合、もう一度マウスでボタンをクリックしない限りは「選択状態」に戻らないので非常に面倒な事になります。

ここら辺はWindowsフォームのようにLostFocusイベントが検知されれば良いのですが、現状では自力で何とかするしかないようです。

◇プライバシーポリシー

●個人情報の利用目的

当ブログでは、メールでのお問い合わせ、メールマガジンへの登録などの際に、名前(ハンドルネーム)、メールアドレス等の個人情報をご登録いただく場合がございます。

これらの個人情報は質問に対する回答や必要な情報を電子メールなどをでご連絡する場合に利用させていただくものであり、個人情報をご提供いただく際の目的以外では利用いたしません。

●個人情報の第三者への開示

当サイトでは、個人情報は適切に管理し、以下に該当する場合を除いて第三者に開示することはありません。

・本人のご了解がある場合
・法令等への協力のため、開示が必要となる場合

個人情報の開示、訂正、追加、削除、利用停止
ご本人からの個人データの開示、訂正、追加、削除、利用停止のご希望の場合には、ご本人であることを確認させていただいた上、速やかに対応させていただきます。

アクセス解析ツールについて

当サイトでは、Googleによるアクセス解析ツール「Googleアナリティクス」を利用しています。

このGoogleアナリティクスはトラフィックデータの収集のためにCookieを使用しています。このトラフィックデータは匿名で収集されており、個人を特定するものではありません。
この機能はCookieを無効にすることで収集を拒否することが出来ますので、お使いのブラウザの設定をご確認ください。

●免責事項

当サイトからリンクやバナーなどによって他のサイトに移動された場合、移動先サイトで提供される情報、サービス等について一切の責任を負いません。

当サイトのコンテンツ・情報につきまして、可能な限り正確な情報を掲載するよう努めておりますが、誤情報が入り込んだり、情報が古くなっていることもございます。

当サイトに掲載された内容によって生じた損害等の一切の責任を負いかねますのでご了承ください。

●プライバシーポリシーの変更について

当サイトは、個人情報に関して適用される日本の法令を遵守するとともに、本ポリシーの内容を適宜見直しその改善に努めます。

修正された最新のプライバシーポリシーは常に本ページにて開示されます。