【Unity】uGUIをゲームパッドやキーボードに対応させる

はじめに

uGUIでButtonを作った際は、OnClickやEventTriggerで入力検知を行ないます。

OnClickというメソッド名の時点でお察しですが、これらはデフォルトだとマウス入力にしか対応していません。試しにテキトーにButtonを生成して実行してみてください。キーボードで上下入力をしたり、Enterを押しても、うんともすんとも言いません。

このような場合、Scriptで現在選択中のButtonを保存する変数を用意し、Inputでキー入力を検知して別のButtonをハイライトしたりOnClickを呼び出す……といった、ゴリゴリとScriptを書いていくやり方が考えられますが、正直面倒くさいですよね。

実は、Scriptは全く書かなくていい……とは言いませんが、2行だけでキーボードやパッド入力には対応できます。
意外と知られていないので、実装手順をまとめておきます。

実装手順

Selectable.Select() を呼び出す

ButtonやSliderといった選択可能なuGUIは、Selectableというクラスを継承しています。SelectableにはSelectというメソッドがあり、これを呼び出すことで自身をハイライト状態にできます。

テキトーにButtonを縦に並べて、このScriptを一番上のButtonにアタッチしてみてください。キーボードで操作できるはずです。

Navigationでハイライト先を細かく指定

さて、実際に試した方はお気づきでしょうが、この方法だと選択項目のループができません。要するに、一番下を選択した状態で更に下を押すと、一番上に戻る処理が実装されていません。

ハイライト先を細かく指定したい場合は、SelectableのNavigationの項目を使います。

Automaticになっているところを、Explicitにすると、遷移先を手動で選択できるようになります。Visualizeを押すとSceneビューにて矢印で示されるようになり、視覚的に分かりやすくなります。

なお、ButtonやSlider、InputFieldにScrollbarなど、マウスで反応するものは全てSelectableを継承しているので、Navigation項目があります。ない場合もSelectableをアタッチすればOKです。

スポンサードサーチ

EventSystemでキー入力の詳細を決める

EventSystemって、普段は意識しませんよね。uGUIの作成時に自動でひっついてくる、よく分からないオブジェクトという認識です。

正直今もその認識は変わっていませんが、このEventSystemを編集することでキー入力の挙動をカスタマイズできます。

Standalone Input Module

EventSystemの、これまた自動でアタッチされているStandalone Input Moduleを編集します。

最初の上4つは、上下左右と決定キャンセルを、Input Managerのどのキーに割り振るかです。ここをいじることはあまり無いと思います。

その下のInput Action Per Secondは、押し続けた際の連続遷移をどの程度早くするかです。数値を増やすほど、押しっぱなしにした際の遷移速度が上がります。

Repeat Delayは、どれくらい長く押し続ければ連続遷移を開始するかの秒数指定です。0.5なら、0.5秒間押し続けると押しっぱなしと認識され、項目が連続で遷移します。

キーを押したことによって具体的にどのようなイベントが発行されるかは、Unity公式のドキュメントに詳しく載っています。

選択状態を指定

ちなみに、初期状態の指定ならScriptを書かずともEventSystemから指定できます。

EventSystemのFirst Selected で指定します。先ほどのScriptは削除してOKです。

マウス入力と両立させる

マウスと並行入力するとバグる

これで解決……と思いきや、オンマウスしたままキーボードやパッドで上下入力をすると、選択項目が2つに増えてしまいます。

UIによっては、選択項目を複数にしたい場合もあるため、デフォルトでは自動で非選択状態にする処理は組まれていません。

また、マウスをButtonから離すと選択状態が解除されますが、一度解除されるとキーボードで選択できなくなってしまいます。

これらの問題を解決する……要するにマウスと両立させるには、ひと工夫必要です。

具体的には、

  • オンマウス時に選択状態を解除
  • マウスが離れた際に選択状態にする

とすることで、マウスと両立できるようになります。

Scriptを追加する

上記を実装するにあたり、必要なScriptの記述は1つ。
「指定のSelectableを非選択状態にする」だけです。

選択状態にするにはSelectを使えばいいんでしたね。非選択状態はUnSelect……と簡単には行きません。そんなメソッドはありません。

非選択状態にするには、
EventSystem.current.SetSelectedGameObject (null);
と記述してやります。

EventSystemについては先ほど簡単に触れましたが、こいつがどのObjectを選択しているかを管理しています
(正確には、 EventSystem.current です)。

SetSelectedGameObject で指定のGameObjectを選択状態にします。つまり、Selectも

EventSystem.current.SetSelectedGameObject (gameObject);

と 置き換えることができます。ここにnullを指定すれば、何も選択していない状態になるわけです。

これらをもとに、Scriptを修正します。

  1. 上記Scriptを、操作対象のButton全てにアタッチ
  2. 全てのButtonにEventTriggerをアタッチ
  3. PointerExitにSelectSelfを、PointerEnterにNonSelectSelfをアタッチ

これで、マウスと両立した入力操作が可能になります。

まとめ

以上、簡単な概要をまとめました。一時期流行ったリングメニューや、モンハンのアイテム選択のような凝ったメニューの場合は対応できませんが、 基本的なUIであれば、ほぼScriptを書かずに済みます。

記事をシェアする