うにてぃブログ

主にUnityとC#に関する記事を書いていきます

【Unity】特定の状況で GraphicRaycaster の enable を変更するとタップの順番が変化する

特定の状況で GraphicRaycaster の enable を切り替えると、

タップ判定が変わることがあったため、その状況と原因について記述する



以下のオブジェクトの配置で 以下のコンポーネントがついている状態で確認する

f:id:hacchi_man:20211117001740p:plain

Rootのコンポーネント

f:id:hacchi_man:20211117001824p:plain:w300

Canvas1, Canvas2コンポーネント

f:id:hacchi_man:20211117001852p:plain:w300

Canvas1, Canvas2 のRectTransform

f:id:hacchi_man:20211117001955p:plain:w300

SampleMonoBehaviour は以下のようにタップした場合にオブジェクト名をログに出す

using UnityEngine;
using UnityEngine.UI;
 
public class SampleMonoBehaviour : MonoBehaviour
{
    [SerializeField]
    private Button _button;
 
    private void Awake()
    {
        _button.onClick.AddListener(() => Debug.Log(transform.name));
    }
}

タップしてみる

この状態でタップしてみると Hierarchy 上で下にある Canvas2 の名前が表示される

f:id:hacchi_man:20211117002119p:plain

GraphicRaycaster の enable を切り替えて戻す

GraphicRaycaster.enable = false;
GraphicRaycaster.enable = true;

上記のように GraphicRaycaster を一度無効にしてから、有効にする

再度タップしてみる

再度タップすると、先程と同じ Canvas2 の名前が表示されるかと思いきや Canvas1 が表示される

f:id:hacchi_man:20211117002329p:plain

原因調査

なぜ順番が変わったのか原因を調査する

そのためにまず GraphicRaycaster の親クラスである BaseRaycaster を覗いてみる

OnEnable を見てみると RaycasterManager.AddRaycaster(this); とあるため登録処理をしていることが分かる

RaycasterManager では特に複雑な処理はしていない

呼び出しの順番を見る

BP を設定しどちらの GraphicRaycaster が先に登録されるのかを見てみると、Canvas2 が先に登録されていた

先程のように Canvas2 を無効にして、有効にした場合 Canvas1 が先頭に来ることになる

タップ判定処理

タップした結果をこちら で行っている

他の値が一緒の場合、関数の最後の index で比較されこの index は RaycasterManager の登録順が入るため Canvas1 が優先になりタップ判定が変わったことが分かった

結論

GraphicRaycaster の enable を切り替える場合は SortOrder 等を適切に設定すべき