この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
Unityを使っていて実装で詰まったところの備忘録としてUIが重なった時の処理を書いていきます。 主に、EventSystemについて書いていきたいと思います。 EventSystemで制御している時は、EventSystemを介して制御しましょうと言う話です
はじめに
こんにちは、初めまして。今回初めて投稿させていただきます新卒でエンジニアとして入社した者です。
今回、Inputを使ったクリックイベントを実装しました。しかしEventSystemはそのクリックイベントには干渉してこないので何かしらのオブジェクトが重なってもInputのクリックイベントが実行されてしまうと言うバグが出ました。
その時のEventSystemで制御する方法を書いていきます。
EventSystem とは
これは、UIのイベントを制御するオブジェクトで、Unity上の入力をうまく処理してオブジェクトにイベントを送信する仕組みのことです。基本的にUnityのuGUIはこれで管理されています。
なぜこのバグが起こったのか?
このバグが起こった原因は、EventSystemとInputクラスの処理が連携していないことに原因がありました。
EventSystemは上記の通り、uGUIの入力を管理するコンポーネントです。ボタンなどに対しての入力エベントを管理しています。
対してInputクラスは座標を取得してその座標内にオブジェクトがあるならば、クリックイベントを実行する実装になっていました。
これでは、どちらも独立しているので、座標でイベントを管理しているとどんなにUIが重なってもその場所がタップされると実行されてしまうという状況でした。
解決方法
解決方法として、複数方法がありました。
- raycastでどのオブジェクトが重なっているかを判定して一番上にあるもののクリックイベントを実行する方法
- IPoinerClickHandlerインターフェースを使い、InputをEventSystemに組み込んで実装する方法
今回は後者で実装しました。
実装方法
IPoinerClickHandlerインターフェースをクラスに実装してください。そうすることで、InputでとっているクリックイベントをEventSystemに組み込むことができます。このようにするとInputクラスでの入力とEventSystemでの入力を連携させることができました。
ソースコードは以下のようになります。
class TestInput : IPoinerClickHandler {
public void OnPointerClick(PointerEventData eventData) {
//ここにタップ処理を追加する
}
}
このインターフェースは様々な種類があります。
詳細は下記URLで詳しく書いてあります。
https://docs.unity3d.com/Manual/SupportedEvents.html
まとめ
EventSystemを挟むことで簡単に制御ができるようになりました。
EventSystemで管理しているUIは、EventSystemを介して制御してあげましょう。そうしないと今回の私のようにバグを生み出してしまうのでやめましょう。
もし、興味のある人はuGUIのソースコードは、BitbacketのUnity Technologies/Unity/UIにて公開されているので読んでみてはいかがでしょうか?