ボタンイベントを登録してコルーチンを呼び出す際、
IEnumerator型に代入して呼び出すと最初の一回しか呼び出せないのはどういった理由からでしょうか?
下記の様にボタン二つを用意して同じコルーチンを「そのまま呼び出す」、「代入して呼び出す」を試しましたが後者の方は一回しか呼び出せません。
C#
1using UnityEngine; 2using System.Collections; 3using UnityEngine.UI; 4 5public class TestCode : MonoBehaviour 6{ 7 [SerializeField] 8 Button[] button = null; 9 10 private void Start() 11 { 12 IEnumerator enumerator = CorutineTest(); 13 14 button[ 0 ].onClick.AddListener( () => StartCoroutine( CorutineTest() ) ); // 何度も呼び出せる 15 button[ 1 ].onClick.AddListener( () => StartCoroutine( enumerator ) ); // 一度しか呼び出せない 16 } 17 18 IEnumerator CorutineTest() 19 { 20 Debug.Log( "A" ); 21 yield return null; 22 } 23}
UnityAction型での関数呼び出しではこういった違いが無いのは確認しています。
UnityAction
はdelegate
、IEnumerator
はinterface
なのでこの辺りの違いから発生している事かと調べていますが詳しい記述がヒットしないので質問させて頂きました。
bboydaisukeさんの回答を受けての追記:デリゲートでの記述
bboydaisukeさんが提示してくれたサイトを参考にコルーチン用のデリゲートを用意してそれに代入して呼び出すように変更すれば問題無く複数回呼び出せるようになりました。
内部的処理の説明などまだ完璧では無いですが対処法は今後大丈夫そうです。
C#
1using UnityEngine; 2using System.Collections; 3using UnityEngine.UI; 4 5public class TestCode : MonoBehaviour 6{ 7 [SerializeField] 8 Button[] button = null; 9 10 private delegate IEnumerator CoroutineDelegate(); 11 12 private void Start() 13 { 14 CoroutineDelegate corutineDelegate = CorutineTest; 15 16 button[ 0 ].onClick.AddListener( () => StartCoroutine( CorutineTest() ) ); // 何度も呼び出せる 17 button[ 1 ].onClick.AddListener( () => StartCoroutine( corutineDelegate () ) ); // 何度も呼び出せる 18 } 19 20 IEnumerator CorutineTest() 21 { 22 Debug.Log( "A" ); 23 yield return null; 24 } 25}
katsukoさんの回答を受けての結論
コルーチンはプログラムを任意の箇所で中断・再開するしくみという認識が正確に出来ていなかったようです。
() => StartCoroutine( CorutineTest() )
は毎回初期位置に戻って呼び出されるのでDebug.Log
が呼ばれる。
() => StartCoroutine( enumerator )
は初期位置に戻らないのでDebug.Log
が呼ばれない。
上記動作の違いがある為に差異が発生していました。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/11/02 06:25 編集
2020/11/02 06:41
2020/11/02 15:41 編集
2020/11/02 06:59
2020/11/02 07:02
2020/11/04 12:47