在 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()
    {

    }
}