読者です 読者をやめる 読者になる 読者になる

いんでぃーづ

個人でゲーム開発してる上で吸収したモノたち紹介。UnityからGIMPまでなんでも。デザインとかゲーム論まで語っちゃうよ的なアレ。

MENU
{スポンサーリンク}

Invoke , Coroutine , SendMessage で文字列を使わない方法

Unity Tips

タイトルにあげた関数は遅延処理、並列処理、オブジェクト間通信を簡単に記述できるので便利なのですが、関数名を文字列で指定して呼び出す場合は注意する必要があります。

Invoke("TestInvoke");

上記のように書き、あとで関数の名前を変更したときに、どうしても文字列の修正漏れが出てしまいます。

それを未然に防ぎたい場合、ここに上げる方法を使えば、修正漏れをコンパイルエラーとして知ることができます。

Invoke の場合

System.Action デリゲート型を使います。

using UnityEngine;
using System.Collections;
using System;

public class TestInvoke : MonoBehaviour {

  void Start () {
    // Invoke
    Invoke (((Action)TestInvokeMethod).Method.Name, 1f);

  }

  public void TestInvokeMethod() {
    Debug.Log("Invoke!");
  }

}

Coroutineの場合

IEnumeratorを使う方法と、Funcデリゲートを使う方法があります。

IEnumeratorを使う

こちらはCoroutineの基本的な使い方でもあります。

using UnityEngine;
using System.Collections;
using System;

public class TestCoroutine : MonoBehaviour {

  void Start () {
    // StartCoroutine (引数あり)
    StartCoroutine (TestCoroutine(1));
  }

  IEnumerator TestCoroutine(int test) {
    Debug.Log(string.Format("Coroutine! : {0}", test));
    yield return new WaitForSeconds(2f);
    Debug.Log("Finish.");
  }
}

StopCoroutineしたい場合はIEnumeratorを保存する必要があります。

public class TestInvoke : MonoBehaviour {
  IEnumerator routine;

  IEnumerator Start () {
    // IEnumeratorを使ったStartCoroutine & StopCoroutine
    routine = TestCoroutine(2);
    StartCoroutine(routine);

    yield return null;

    StopCoroutine(routine);
  }


  IEnumerator TestCoroutine(int test) {
    Debug.Log(string.Format("Coroutine! : {0}", test));
    yield return new WaitForSeconds(2f);
    Debug.Log("Finish.");
  }
Funcデリゲートを使う

Invokeと似た方法です。

StartCoroutine (((Func<int, IEnumerator>)TestCoroutine).Method.Name, 1);

止める場合は

StopCoroutine(((Func<int, IEnumerator>)TestCoroutine).Method.Name);

SendMessage の場合

たいていの場合は別クラスの関数名を使いたいと思うので、どこかに文字列の変数としてとっておく必要があります。

受信する側

public class TestReceiveMessage : MonoBehaviour {
  static public string SendMessageMethod;

  void Start () {
    SendMessageMethod = ((Action)ReceiveMessageMethod).Method.Name;
  }

  void ReceiveMessageMethod() {
    Debug.Log("Receive Message!");
  }

}


送信する側

public class TestSendMessage : MonoBehaviour {

  public GameObject target;

  void Start () {
    // targetは受信する側にリンクしておく
     target.SendMessage(TestInvoke.SendMessageMethod);
   }

Amazon.co.jpアソシエイト