在 Unity 中,物体之间的通信除了可以使用 SendMessage 系列方法之外,还可以通过 delegate(委托)来实现。相比 SendMessage 的字符串反射方式,基于委托的事件派发更高效,也更便于在编译期发现问题。
下面给出一对最小示例:EventDispatcher 负责定义并在合适时机触发事件,Listener 负责把自己的回调方法注册到该事件上。同一个委托可以挂载多个回调,触发时会依次调用。
Listener
监听者在 Start 中找到挂有 EventDispatcher 组件的目标对象,然后把 OnEvent 方法注册到其事件委托上。这里特意注册了两次,用来演示多播委托的叠加效果;如果改用 = 赋值,则会覆盖已有的回调列表。
Listener:
using UnityEngine;
using System.Collections;
public class Listener : MonoBehaviour {
// Use this for initialization
void Start () {
EventDispatcher ev = GameObject.Find("Cube").GetComponent<EventDispatcher>();
ev.ev += OnEvent;//可装载多个delegate
ev.ev += OnEvent;
// ev.ev = OnEvent;
}
void OnEvent(GameObject obj)
{
Debug.Log(obj.ToString() + "123" );
}
// Update is called once per frame
void Update () {
}
}
EventDispatcher
派发者通过 delegate 声明事件签名,并暴露一个 EventHandle 类型的字段 ev 供外部订阅。在 Start 阶段先判空,再把自身的 gameObject 作为参数触发事件,所有已注册的回调都会被调用。
EventDispatcher:
using UnityEngine;
using System.Collections;
public class EventDispatcher : MonoBehaviour
{
public delegate void EventHandle(GameObject obj);
public EventHandle ev;
// Use this for initialization
void Start()
{
if (ev!=null)
{
ev(this.gameObject);
}
}
// Update is called once per frame
void Update()
{
}
}