@ssf1200

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

Unity コルーチンについての質問

Q&A

Closed

解決したいこと

Unityで、コルーチンについて分からないことがあり、質問をしたいです。

該当するソースコード

using System.Collections;
using UnityEngine;

public class CoroutineSample : MonoBehaviour
{
    private Coroutine coroutine;
    void Start()
    {
        coroutine = StartCoroutine(SampleA());
    }
    private IEnumerator SampleA()
    {
        yield return SampleB();
        if (coroutine != null) Debug.Log("Bad");
        if (coroutine == null) Debug.Log("Good");
    }
    private IEnumerator SampleB()
    {
        coroutine = null;
        Debug.Log("null");
        yield return null;
    }
}

これを実行してみたところ、下の画像のように
Debug.Log("null");
Debug.Log("Bad");
の順でコンソールに表示されました。
先にcoroutine = null;になっているのなら、
if (coroutine == null) Debug.Log("Good");の方が表示されると思ったのですが、違いました。
なぜこのような結果になるのか質問をしたいです。

スクリーンショット (2415).png

自分で試したこと

 private IEnumerator SampleB()
 {
     yield return null;
     coroutine = null;
     Debug.Log("null");
     yield return null;
 }

このように、 SampleB()において、coroutine = null;の前に 
yield return null;やyield return new WaitForSeconds(1f);
などの間を挟むと、
Debug.Log("Good");の方が表示されるようになりましたが、
それもなぜなのかよく分かりません。

0 likes

1Answer

順を追ってみましょう。

StartCoroutine(SampleA()) ではSampleAの最初の1歩が動く。(Unityの仕様)
SampleAの最初の1歩では、yield return SampleB(); でSampleBのイテレーターを獲得してこれを返す。
Unityは別のイテレーターが返されたので即座にSampleBの最初の1歩を実行する。
ここで coroutine にnullが代入され、コンソールに"null"が出力される。
SampleBは yield return null; まで進んで一時停止し、ここでようやくStartCoroutine全体の処理が完了できるようになって、Coroutine型のリターン値が返される。それ(!= null)が coroutine に代入される。

次のフレームでは、SampleBは再開し、(終わりに到達したので)終了する。子が終了したのでSampleAは次の処理に進むことができ、if文に進んで "Bad" が出力される。

<自分で試したこと>のコードの場合

SampleBの最初の1歩が実行されるところまでは同じ。

SampleBの最初の1歩ではすぐにyield returnするので何も起きない。
結果、coroutine には非nullの値が代入されるのも同じ。

次のフレームでは、SampleAは子のSampleBが終わっていないので足踏み、SampleBで coroutine = null が実行され、その次の yield return null; で一時停止。

その次のフレームではSampleBは再開して終了。SampleAが進むことができるようになる。このとき coroutine にはnullが代入されているので "Good" が出力される。

1Like

Comments

  1. @ssf1200

    Questioner

    理解できました!
    丁寧に解説していただき、ありがとうございます。

Your answer might help someone💌