うにてぃブログ

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

【Unity】YieldInstruction の落とし穴

WaitForSecondsWaitUntilWaitWhile などは YieldInstruction を継承したクラスで
IEnumerator 内で待ちに利用するのに便利なのですが少し問題があります

GC Alloc発生

このクラスは下記のような使い方をすることが多いと思うのですが
この使い方をした場合毎呼び出しの際に 20 B のゴミ (GC Alloc) が発生してしまいます

f:id:hacchi_man:20200409232846p:plain

yield return new WaitForSeconds(0.01f);

そのため利用する場合は一度インスタンスを作成しておき、それを使い回すとゴミが出ずに利用できます

   private IEnumerator Start()
    {
        var wait = new WaitForSeconds(0.001f);
        while (true)
        {
            yield return wait;
        }
    }

条件を満たした際の処理

下記コードはどちらも valid が true になるのを待っている処理です

   private IEnumerator Start()
    {
        var valid = true;
        while (!valid)
        {
            Debug.Log("Call While");
            yield return null;
        }
        
        var wait = new WaitUntil(() =>
        {
            Debug.Log("Call WaitUntil");
            return valid;
        });

        yield return wait;
    }

これを実行したログは下図になります

f:id:hacchi_man:20200409232907p:plain

WaitUntil だけ条件を満たしているのに1回処理が行われてしまいます

そのため 条件を満たす場合は 1フレームも待ちたく無い場合はこれを利用してしまうと
待ちが発生してしまうため処理によっては while を使ったほうがいいことがあります