Closed1

await UniTask.WaitUntilで取得待ちでつまずいた件

eisukeeisuke

問題

クラスの取得待ちをWaitUntilで表現しようとしたができなかった。

該当のコード

(sceneName == VRMatchingConstants.SCENE_NAME_VALUE_HARMONYHOUSESCENE)
                {
                    Debug.Log($"ハーモニーハウスのビルド開始!!");
                    _vrPlayerLifeTimeScope = FindObjectOfType<VRPlayerLifeTimeScope>();
                    await UniTask.WaitUntil(() => _vrPlayerLifeTimeScope != null);
                    _vrPlayerLifeTimeScope.Build();
                    Debug.Log($"ビルド開始!!");
                }

FindObjectOfType<T>で取得してWaitUntil取得し中身が入るまで待つという実装をしたつもりだった。

解決方法

else if (sceneName == VRMatchingConstants.SCENE_NAME_VALUE_HARMONYHOUSESCENE)
                {
                    Debug.Log($"ハーモニーハウスのビルド開始!!");
                    await UniTask.WaitUntil(() => _vrPlayerLifeTimeScope = FindObjectOfType<VRPlayerLifeTimeScope>());
                    _vrPlayerLifeTimeScope.Build();
                    Debug.Log($"ビルド開始!!");
                }

WaitUntil内でFindObjectOfType<T>する事。

GPT-4様による解説

FindObjectOfType<VRPlayerLifeTimeScope>() がすぐに対象のオブジェクトを見つけられない場合、このコードで問題が発生することがあります。

このコードでは、まず _vrPlayerLifeTimeScope を FindObjectOfType<VRPlayerLifeTimeScope>() で初期化しています。しかし、この時点で VRPlayerLifeTimeScope オブジェクトがまだシーンに存在しないか、準備が整っていない場合、FindObjectOfType は null を返します。

その後、await UniTask.WaitUntil(() => _vrPlayerLifeTimeScope != null); で、_vrPlayerLifeTimeScope が null でなくなるまで待機しています。しかし、_vrPlayerLifeTimeScope の初期化はすでに行われており、null のままであることが問題です。このコードでは、FindObjectOfType が再試行されることはありませんので、_vrPlayerLifeTimeScope が null のままになることがあります。

この問題を解決するには、2つ目のコードのように、UniTask.WaitUntil の条件式の中で _vrPlayerLifeTimeScope を初期化する方法があります。この方法では、条件が満たされるまで FindObjectOfType が繰り返し実行され、VRPlayerLifeTimeScope オブジェクトがシーンに現れるのを待つことができます。

要するに

WaitUntil内にFindObjectOfType<T>を書くと取得するまで何度も探し続けるみたいです。

このスクラップは2023/05/02にクローズされました