【Unity】UIが反応しないときはこの3つをチェック!

【Unity】UIが反応しないときはこの3つをチェック!

ゲームを作っている途中でありがちなのが、

「あれ……? ボタンが反応しないよ……?」

という悩み。

ゲーム実行中にボタンをクリックしても、カチカチと音が響き渡るだけ。なんてときに確認したいのが以下の3点。

  1. シーン内にEventSystemがあるか
  2. ボタンのOnClick()は設定してあるか
  3. RaycastTargetがTrueのUIが手前にないか

特に3番目は画面内のUIが増えてくると重なりまくって起こりがちです。画面付きで解説するので、ひとつひとつ確認してもらえるといいかも。

 

環境

macOS 10.14 Mojave

Unity2018.3.14f1

Unity Hub 2.1.0

シーン内にEventSystemがあるか

EventSystemはあるかな?
EventSystemはあるかな?

 

シーンのHierarchyウィンドウにEventSystemオブジェクトがない場合、ボタンをクリックしたことが検知されません。カチカチ音が響き渡ります。

通常、シーン内で何らかのUI要素(ImageやTextなど)を作成したとき、自動的にEventSystemオブジェクトが作成されます。

しかし、Prefab化したUIをシーンに配置したり、Canvasをそのままコピーして別のシーンに配置したりするとEventSystemオブジェクトは作成されないんです。

例えば、Canvasをコピーして別のシーンに持っていくことを考えます。『UICheck』というシーンでCanvasをコピーします。

Canvasをコピー
Canvasをコピー

 

『UICheck2』というシーンを作成し、ペーストします。

別のシーンを作ってペースト
別のシーンを作ってペースト

 

すると……なんと、EventSystemオブジェクトがないままコピーされました。コピーの対象に入れていないので当然っちゃ当然なのですが、急いでいるときにはEventSystemオブジェクトがないことに気付かないこともあります。

EventSystemは作られない
EventSystemは作られない

 

ちなみにこの状態でButtonオブジェクトを作成しても、EventSystemオブジェクトは作成されません。こうなるとテストプレイするまで多分気付きませんね。

Buttonを作成
Buttonを作成

 

ボタンのOnClick()は設定してあるか

OnClick()の設定忘れ
OnClick()の設定忘れ

 

これもよくありがちですが、スクリプトでボタンを押した時の動作を書いたにもかかわらず、ButtonコンポーネントのOnClick()で設定を忘れるパターンです。

「スクリプトの処理はちゃんと書けてるのに……」なんて思っていても、Unityエディタでの操作を忘れていたら動いてくれません。

スクリプトを書いた後ってすぐに動作確認したくなってしまうので、結構やっちゃいがちです。慣れてくればすぐここに気付くと思います。

また、OnClick()で呼ぼうとしているメソッドが見つからない場合は、対象のメソッドがpublicになっているかも確認します。

ボタン関係でもうひとつ思い浮かんだケースが、ボタンコンポーネントのinteractableがfalseになっている場合。デフォルトだとボタンの色が変わるので気付くと思いますが、これも念の為確認しておくといいでしょう。

ひとつひとつ確認するのが大事ですね。

RaycastTargetがTrueのUIが手前にないか

見落としがちなRaycastTarget
見落としがちなRaycastTarget

 

「EventSystemもシーン内にあるし、ButtonのOnClick()だって設定してある。でもなんでボタンが反応しないの?」

という時の犯人は大体RaycastTargetです。

Raycastはグラフィックの上にカーソルやポインタがあるかどうかを確認する機能です。

イメージとしては、クリックした時にマウスカーソルからRay(光線)が出て、それが何かのUI(例えばボタン)に当たったら「今ボタンの上にカーソルがあります」と判断する感じです。

このRaycastを受け取るかどうかの設定がRaycastTargetで、TextやImageに設定があります。ボタンオブジェクトの場合は、Buttonコンポーネントと一緒にアタッチされているImageコンポーネントの側でRaycastTargetの設定を持っています。

ポイントは何かのUIに当たったらそこで処理が終了すること。

複数のUIが重なっていると、画面から見て一番手前のRaycastTargetがTrueのUIに当たった時点で処理が終わり、その後ろにあるUIについては判定が行われません。Hierarchyウィンドウで上にあるオブジェクトは画面奥、下にあるオブジェクトは画面手前に描画されます。

つまり、ボタンの手前にRaycastTargetがTrueになっているTextやImageがあると、ボタンの上にカーソルがあると認識されず、ボタンに対するクリックも認識してくれないことに。Unityの中では手前のTextやImageがクリックされたと認識されるんですね。

Textの場合は、Textフィールドに入力されている内容に比べてWidthやHeightが大きい場合にボタンと重なっていることがあります。

Imageの場合はアルファが0(透明)になっていると重なっていることに気付きにくいです。例えば画面全体を覆うマスク用の画像でRaycastTargetがTrueになっていて、アルファを0にして画面を表示したときにボタンが反応しない、なんてことがあります。

なので、大きさの調整を行なったり、そもそもクリックが必要ないTextやImageではRaycastTargetをFalseにしておくと良いかもしれません。

RaycastTargetの場所

分かりやすいコンポーネント、分かりにくいコンポーネントがあるので画像で確認しましょ。

Image

ImageのRaycastTarget
ImageのRaycastTarget

 

Imageコンポーネントでは一番下にあります。項目数が少ないので分かりやすいですね。

Raw Image

RawImageのRaycastTarget
RawImageのRaycastTarget

 

Raw Imageの場合はUV Rectの項目が増えているので、その上にあります。

Text

TextのRaycastTarget
TextのRaycastTarget

 

Textコンポーネントでは一番下にあります。項目が増えるのでちょっと戸惑うかもしれません。

Text Mesh Pro – Text

Text Mesh Pro - TextのRaycastTarget
Text Mesh Pro – TextのRaycastTarget

 

ザ・分かりにくい代表。

コンポーネントの下の方、デフォルトでは折りたたまれている『Extra Settings』の中にあります。

結構見落としがちなので注意。

Button

ButtonのRaycastTarget
ButtonのRaycastTarget

 

Buttonオブジェクトの場合は、Buttonコンポーネント本体ではなく、一緒にアタッチされているImageコンポーネントにRaycastTargetの設定が含まれています。

ポイントはButtonコンポーネントの『Target Graphic』です。ここで指定されたImageのRaycastTargetを見ています。

Buttonオブジェクトと同様に、ToggleやDropdown、Sliderなどのオブジェクトは、『Target Graphic』で指定されているImageがRaycastTargetの設定を持っているので、そちらを確認します。

といっても、これらのオブジェクトの場合はRaycastTargetをFalseにすることは無いと思うので、念の為の確認項目として考えてもらえればいいかもしれません。

まとめ

今回はUIが反応しないときに確認したい3つのポイントをお伝えしました。

  1. シーン内にEventSystemがあるか
  2. ボタンのOnClick()は設定してあるか
  3. RaycastTargetがTrueのUIが手前にないか

個人的に3番目のRaycastTargetに引っかかることが多いので、もし画面をクリックしても反応が無い場合はチェックしてみてください。

「こういうケースもあるよ!」という素敵なアイディアがあったらコメ欄に書いていただけると助かります。

アプリ公開までの攻略チャートを作りました!

CTA-IMAGE

「スマホ向けのアプリを作ってみたいけど、何から手を付けていいか分からない!」


そんなお悩みをお持ちの方向けに、todoがアプリをリリースした経験から手順や考慮すべき点をまとめたe-bookを作成しました。ゲーム作りはそれ自体がゲームのように楽しいプロセスなので、「攻略チャート」と名付けています。


アプリをリリースする観点から書いているので各アプリストア向けの作業が入っていますが、企画、設計、開発、テスト部分については他のプラットフォームでも使える知識が満載です。


無料で入手できるのでぜひお早めにゲットして、開発をブーストさせてください!