ステートマシンで遊んでて、状態を管理するクラスと実際の処理を行うクラスを分けたかったので、他のクラスのコルーチンを呼び出す方法を探してみました。
想定
以下のような呼び出しをしたくて、更に呼び出し先コルーチンはインスペクタ上から設定できるようにする方法を考えました。
class ClassA
{
void Start()
{
なんらかの方法でここから ClassB の TestCoroutine を呼びたい
}
}
class ClassB
{
public IEnumerator TestCoroutine()
{
呼ばれたいー
}
}
やってみたこと(そして諦めたこと)
delegate でできそうに見えたのですが、インスペクタ上から設定する方法を考え出せず断念。
Action やら何やら考えてみたけど思いつきませんでした。
ぐぐった
ずばり正解を書いてくださっている方がおりました。(外部サイト)
【Unity】Invoke、StartCoroutineを別スクリプトのメソッドへ使う
地面に頭こすりつける程感謝。
言われてみればそのとおりで、StartCoroutineって何者よ?
というのを冷静に考えればよかったのですね。。
作ってみた
ClassA.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ClassA : MonoBehaviour
{
[SerializeField]
private GameObject otherObject;
[SerializeField]
private string coroutineName;
// Start is called before the first frame update
void Start()
{
Debug.Log("Start");
var otherInstance = otherObject.GetComponent<ClassB>();
otherInstance.StartCoroutine(coroutineName, new Dictionary<string, string>(){
{"foo", "hello"},
{"bar", "world"}
});
Debug.Log("Coroutine Started");
}
}
ClassB.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ClassB : MonoBehaviour
{
IEnumerator TestCoroutine(Dictionary<string, string> param)
{
Debug.Log(param["foo"]);
yield return new WaitForSeconds(3.0f);
Debug.Log(param["bar"]);
yield return new WaitForSeconds(3.0f);
Debug.Log("Coroutine Finished");
yield break;
}
}
それぞれのスクリプトを適当なGameObjectにそれぞれアタッチして、
インスペクタから ClassA の otherObject
に ClassB の参照を、coroutineName
に TestCoroutine
と文字列で入力し実行しました。