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

196の日記

完全に開発メモと雑談、その他忘れそうな計算式などを書き溜める場所になっています!

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

unity

タイトル通りです。

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


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