[Unity][C#]StopCoroutineが動かない

Coroutineの挙動が不信だったので調べてみたのでメモ。

当初の状況

あれ?yield return www;してるからwwwインスタンスがデータ取得してからでないと次進まないはず

にも関わらずwww.textよめねーぞって怒られる。なんでだ…?

Reset()もできずハマる。

今回の問題点と目的

  1. coroutineはStopCortoutineした後に同じメソッドをStartCoroutineするとStopしたところから再開するんじゃ?疑惑の解消
  2. Start/Stopの動きを先ず確認
  3. 進む原因は?

ダメなソース

using UnityEngine;
using System.Collections;

public class coroutine : MonoBehaviour {
	
	// Use this for initialization
	IEnumerator Start () {
		
		StartCoroutine(Test());
		Debug.Log("StartCoroutine 1");
		
		yield return new WaitForSeconds(2f);
		
		StopCoroutine("Test");
		Debug.Log("StopCoroutine");
		
		
		yield return new WaitForSeconds(2f);
		
		StartCoroutine(Test());
		Debug.Log("StartCoroutine 2");
		
	}
	
	IEnumerator Test() {
		
		Debug.Log("Test Start");
		
		yield return new WaitForSeconds(1f);
		Debug.Log("1 second");
		yield return new WaitForSeconds(1f);
		Debug.Log("2 second");
		yield return new WaitForSeconds(1f);
		Debug.Log("3 second");
		yield return new WaitForSeconds(1f);
		Debug.Log("4 second");
		yield return new WaitForSeconds(1f);
		Debug.Log("5 second");
		
		
		Debug.Log("Test End");
		
	}
	
	
	// Update is called once per frame
	void Update () {
	
	}
}

結果

コンソールにはこんな表示が。
StopCoroutine doesnt work

StopCoroutine()した後も元気に走り続けるTest()の姿が!

原因は、文字列ではなくハンドラを直接StartCoroutine()に渡していた事。
StopCoroutine()は文字列で受取った指定のCoroutineしか参照できず、あたかも処理を完遂したかの様にエラーも出さなきゃ警告も出ない。

修正

using UnityEngine;
using System.Collections;
using System.Collections.Generic;


public class coroutine : MonoBehaviour {
	
	// Use this for initialization
	IEnumerator Start () {
		
		StartCoroutine("Test");
		Debug.Log("StartCoroutine 1");
		
		yield return new WaitForSeconds(2f);
		
		StopCoroutine("Test");
		Debug.Log("StopCoroutine");
		
		
		yield return new WaitForSeconds(2f);
		
		StartCoroutine("Test");
		Debug.Log("StartCoroutine 2");
		
	}
	
	IEnumerator Test() {
		
		Debug.Log("Test Start");
		
		yield return new WaitForSeconds(1f);
		Debug.Log("1 second");
		yield return new WaitForSeconds(1f);
		Debug.Log("2 second");
		yield return new WaitForSeconds(1f);
		Debug.Log("3 second");
		yield return new WaitForSeconds(1f);
		Debug.Log("4 second");
		yield return new WaitForSeconds(1f);
		Debug.Log("5 second");
		
		
		Debug.Log("Test End");
		
	}
	
	
	// Update is called once per frame
	void Update () {
	
	}
}

これだと以下のように動く。

StopCoroutine work

ちゃんとStopCoroutineで止まってくれた。

そして疑惑だった途中再開もされていない。文字列で指定すればStopCoroutine()もちゃんと機能するということも分かった。

おまけ

  • Startが今回のサンプルの様にIEnumeratorを返すタイプなのにStopAllCoroutines()をするとStartまで止めてしまうので注意。
  • Resetは必要無い。
  • IEnumeratorにparameterを渡す場合は第二引数に入れて上げれば機能する。

参考

C#本

[Unity][C#]StopCoroutineが動かない」への3件のフィードバック

  1. shinriyo

    参考にしました
    StartCoroutineを文字列でやらないとStopCoroutineが効かないのですね?
    では、StartCoroutineに引数付きのを実行したときはうつすべがないのでしょうか。

    返信
    1. Kunihiro OHGAKI

      shinriyo さん
      こんにちは。コメント有難うございます。

      引数付きで文字列指定のハンドラStartCoroutineに渡すには、第二引数以降のパラメータとして実行することで可能です。
      IEnumerator Start(){
      StartCoroutine(“Test”,1);
      yield return new WaitForSeconds(1f);
      StopCoroutine(“Test”);
      }
      IEnumerator Test(int i){
      Debug.Log(“TestStartWith:”+i);
      yield return new WaitForSeconds(2f);
      Debug.Log(“TestEndWith:”+i);
      }

      返信

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です