Open2

IPointerClickHandlerについて理解をちょっとだけ深めるの会

プラカヴィプラカヴィ

先日作成したゲームにこんなコメントを頂きました。

う、うわあああああああああ!!!
ガラガラドンガラガッシャン(椅子から転げ落ちる音)

何でこうなったのか?

実はですね、私の実装ですとクリックイベントの取得にはIPointerClickHandlerを用いていましたが……

このIPointerClickHandlerの使い方について誤解していた部分があり、それが要因で期待してた動作にならなかったのが原因です

まずは動作の確認

このIPointerClickHandlerの動作を確認します。

このように、「Skip」なる空のGameObjectにスクリプトを貼り付いています。
張り付けたスクリプトは簡略化すると以下のようになってます


public class RewardSkip : MonoBehaviour, IPointerClickHandler
{
    public void OnPointerClick(PointerEventData eventData)
    {
      //次のステージに進む
    }
}

見ての通り、IPointerClickHandlerを実装し、クリックしたら何らかの反応をするスクリプトです。
このSkipオブジェクトに以下のような画像を子として持たせます

このオブジェクトはImageコンポーネントを設定してあって、そのプロパティとしてレイキャストターゲットを持っています。
このレイキャストターゲットを含むコンポーネントがないとIPointerClickHanderは反応しないようです
試しに外すと反応しなくなる。

ですのでこれは期待通りの反応です。

期待していた動作

次に私が実装した問題個所です。
IPointerClickHandlerをインターフェースに入れたスクリプトを入れ子にした部分がありました。


Reward1というオブジェクトの子にCardNaiNai(Clone)というオブジェクトを入れ子にしていたわけですが、
この2つのオブジェクトにはそれぞれ別々のスクリプトがIPonterClickHandlerを実装していました。
この場合、親のスクリプトであるReward1のスクリプトのイベントを認識して欲しかったわけですが……

その結果子の方(CardNaiNai)のイベントを認識しているようです ひえー

修正

今回は子の方のスクリプトをenable=falseして無効化しました。
これによってIPointClickHandlerが親の方のイベントのみを取得するようになり、無事修正できたと思います。

まとめ

IPointClickHandler使ったもの同士を入れ子にしない
あと、レイキャスト持ってるコンポーネントが自身または子にないと反応しないようなので注意しよう

プラカヴィプラカヴィ

補足

Q.なんでPC環境だとうまくクリック出来てたの?
A.マウスホバー時に、ホバー用画像を表示しておりまして、
そのホバー用画像がレイキャストを受け入れていたから。です
モバイル環境だとタップ操作の環境で、そのホバー用画像がタップ時には消えていたというミラクル。
おかげで巧妙にモバイルでクリックできなくてPC環境だとクリックできるシチュエーションが生まれていたわけですね……