イベントの使い方色々

Unityには別のコンポーネントにイベントを送信する方法が複数用意されています。 状況に応じて使い分けましょう。

SendMessageで呼び出す方法

特定のゲームオブジェクトに対してメッセージを送信する。

1
this.gameObject.SendMessage(methodName, argument);

BroadcastMessageで呼び出す方法

特定のゲームオブジェクトとその子階層構造に属するゲームオブジェクトにもメッセージを伝播する。

1
this.gameObject.BroadcastMessage(methodName, argument);

直接関数を呼び出す方法

コンポーネントが見つからないとエラーになるので RequireComponent を使用して必要なコンポーネントも自動でアタッチされるうようにしておく。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
using UnityEngine;
using System.Collections;

[RequireComponent(typeof (Receiver))]
public class EventTest : MonoBehaviour {
	private Receiver receiver;
	void OnEvent {
		receiver = this.gameObject.GetComponent<Receiver> () as Receiver;
		receiver.Hoge ("Fuga");
	}
}
1
2
3
4
5
6
7
8
using UnityEngine;
using System.Collections;

public class Receiver : MonoBehaviour {
	public void Hoge (string s) {
		print ("Hoge: "+s);
	}
}

EventHandlerを使用して呼び出す方法

!= nullで存在を確認しないとメソッドが紐付けられていない時にエラーになる。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
using UnityEngine;
using System.Collections;
using System;

public class EventTest : MonoBehaviour {
	[SerializeField] public event EventHandler OnEventHandler;
	public void OnEvent () {
		if (OnEventHandler != null) OnEventHandler (this, EventArgs.Empty);
	}
}

+= を使用して、メソッドを紐付けてもいいし delegate(){} を使ってその場で内容を記述してもいい。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
using UnityEngine;
using System.Collections;
using System;

public class Receiver : MonoBehaviour {
	void Start () {
		this.gameObject.GetComponent<EventTest> ().OnEventHandler += OnEventHandler;
		this.gameObject.GetComponent<EventTest> ().OnEventHandler += delegate(object sender, EventArgs e)
		{
			print ("OnEventHandler: "+ e);
		};
	}
	void OnEventHandler (object sender, EventArgs e) {
		print ("OnEventHandler: "+ e);
	}
}

EventHandlerを使用して呼び出す方法(引数を渡す場合)

引数を渡すには EventArgs を継承したカスタムイベント用のクラスを作らないといけない。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
using UnityEngine;
using System.Collections;
using System;

public class CustomEventArgs : EventArgs {
	public string message;
}
public delegate void CustomEventHandler(object sender, CustomEventArgs e);

public class EventTest : MonoBehaviour {
	[SerializeField] public event CustomEventHandler OnCustomEventHandler;
	public void OnEvent () {
		CustomEventArgs args = new CustomEventArgs();
		args.message = "Fuga";
		if (OnCustomEventHandler != null) OnCustomEventHandler (this, args);
	}
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
using UnityEngine;
using System.Collections;
using System;

public class Receiver : MonoBehaviour {
	void Start () {
		this.gameObject.GetComponent<EventTest> ().OnCustomEventHandler += OnCustomEventHandler;
		this.gameObject.GetComponent<EventTest> ().OnCustomEventHandler += delegate(object sender, CustomEventArgs e)
		{
			print ("OnCustomEventHandler: "+ e.message);
		};
	}
	void OnCustomEventHandler (object sender, CustomEventArgs e) {
		print ("OnCustomEventHandler: "+ e.message);
	}
}

UnityEventを使用して呼び出す方法

public UnityEvent OnUnityEvent; はこれだけでインスペクタ上からメソッドを追加できるようになるので便利。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
using UnityEngine;
using System.Collections;
using UnityEngine.Events;

public class EventTest : MonoBehaviour {
	public UnityEvent OnUnityEvent;
	public void OnEvent () {
		if(OnUnityEvent != null) OnUnityEvent.Invoke ();
	}
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
using UnityEngine;
using System.Collections;

public class Receiver : MonoBehaviour {
	void Start () {
		this.gameObject.GetComponent<EventTest> ().OnUnityEvent.AddListener(OnUnityEventHandler);
		this.gameObject.GetComponent<EventTest> ().OnUnityEvent.AddListener(delegate(){
			print ("OnUnityEvent.AddListener");
		});
	}
	void OnUnityEventHandler () {
		print ("OnUnityEventHandler");
	}
}

UnityEventを使用して呼び出す方法(引数を渡す場合)

引数を追加するには public class CustomUnityEvent : UnityEven<string>{}; などのカスタムイベント用のクラスを作らないといけないので注意。複数の値や他の値を持たせる事ももちろん可。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
using UnityEngine;
using System.Collections;
using UnityEngine.Events;

[System.Serializable]
public class CustomUnityEvent : UnityEvent<string>{};

public class EventTest : MonoBehaviour {
	[SerializeField] public CustomUnityEvent OnCustomUnityEvent;
	public void OnEvent () {
		if(OnCustomUnityEvent != null) OnCustomUnityEvent.Invoke ("Fuga");
	}
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
using UnityEngine;
using System.Collections;

public class Receiver : MonoBehaviour {
	void Start () {
		this.gameObject.GetComponent<EventTest> ().OnCustomUnityEvent.AddListener(OnCustomUnityEventHandler);
		this.gameObject.GetComponent<EventTest> ().OnCustomUnityEvent.AddListener(delegate(string s){
			print ("OnUnityEvent.AddListener: " + s);
		});
	}
	void OnCustomUnityEventHandler (string s) {
		print ("OnCustomUnityEventHandler: "+ s);
	}
}

ExecuteEventsを使用して呼び出す方法

受け手側は先にインターフェースを作り、それを継承する必要がある。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;

public class EventTest : MonoBehaviour {
	public void OnEvent () {
		ExecuteEvents.Execute<IReciever>(this.gameObject, null, (x,y)=>x.OnExecuteEventsHandler("Fuga"));
		ExecuteEvents.Execute<IReciever>(
			target: this.gameObject,
			eventData: null,
			functor: (x,y) => x.OnExecuteEventsHandler("Fuga"));
	}
}
1
2
3
4
5
using UnityEngine.EventSystems;

public interface IReciever :  IEventSystemHandler {
	void OnExecuteEventsHandler(string s);
}
1
2
3
4
5
6
7
8
9
using UnityEngine;
using System.Collections;

public class Receiver : MonoBehaviour, IReciever {
	public void OnExecuteEventsHandler (string s)
	{
		Debug.Log("OnExecuteEventsHandler: " + s);
	}
}