セキュリティ系の勉強・その他開発メモとか雑談. Twitter, ブログカテゴリ一覧
本ブログはあくまでセキュリティに関する情報共有の一環として作成したものであり,公開されているシステム等に許可なく実行するなど、違法な行為を助長するものではありません.

Unity 動的に別のスクリプトに所持しているメソッドを渡す〜UnityEvent

//

タイトル通りです。

今回は制作中のゲームの中で少し複雑なことをしようと思い、今回のことをざっと調べました。そのメモを書きます。


docs.unity3d.com


まぁここを読めば全てわかるんですが、、

例えば以下のようなクラスがあったとします。

using UnityEngine;
using System.Collections;
using UnityEngine.Events;

public class EventTest : MonoBehaviour 
{
     public UnityEvent ev;
     
    void CallAnotherMethod(){
         ev.Invoke();
    }
}

それでもって、別のクラスでこのクラスのevにメソッドをわたあしてあげます。

    bool attack=false;

----------何かの関数内---------
         EventTest eTest=GetComponent<EventTest>();
         eTest.ev.AddListener( PrintDeb);
--------------------------------
    void PrintDeb(){
        attack=true;
        Debug.Log("called");
    }

これで、attackをtrueにし、デバッグを吐く関数をev内に渡すことができました。後は最初のスクリプトのCallAnotherMethod()をどこかで読んであげれば、Invoke()によりev内に保存されていたPrintDeb()が呼ばれます。

ちなみに、引数を渡す関数を指定したいときは、EventUnityをオーバーライドしてやれば、引数を渡すことができます。以下は、リファレンスのコピーです。

using UnityEngine;
using UnityEngine.Events;

[System.Serializable]
public class MyIntEvent : UnityEvent<int>
{
}

public class ExampleClass : MonoBehaviour
{
	public MyIntEvent m_MyEvent;

	void Start ()
	{
		if (m_MyEvent == null)
			m_MyEvent = new MyIntEvent();

		m_MyEvent.AddListener (Ping);
	}

	void Update () 
	{
		if (Input.anyKeyDown && m_MyEvent != null)
		{
			m_MyEvent.Invoke (5);
		}
	}

	void Ping (int i)
	{
		Debug.Log ("Ping" + i);
	}
}


僕はこれを、後から任意のタイミングで生成されるオブジェクトが削除されるタイミングを認知するためのフラグの変化に使用しました。(わかりにくい説明)


まぁOnClickなどもこれを使用して呼ばれているらしいので、感覚的にどんなものなのかは、掴みやすいのではないでしょうか?結構小回りが効くものなので役立ちますが、たくさんのところで使用すると複雑なものになってしまうので(動的に紐づけるとバグなどでスクリプトを見返した時に見落としやすい)、用法用量をお守りください。