事件是一种特殊委托,用于提醒其他类发生了某个事件。
事件与公共多播委托非常相似,它可被视为广播系统;对事件感兴趣的任何类都可以将方法订阅到事件,当发生特定的情况时我们会调用事件进而调用已订阅的方法。

在事件管理类中定义静态事件OnClicked,该类只负责在对应的情况发生后调用事件,同时确保事件不为空否则会出错。
可以看到EventManager事件管理类只留意触发的判断,并不关注TeleportScript和TurnColorScript;同时两个触发方法之间也不需要互相了解

注意:实际上使用公开委托变量也可以替换事件的使用,我们使用事件而不是公开委托变量的原因是事件具有内在安全性,而委托变量没有。通过事件其他类只能订阅和退订,而使用公开委托变量其他类可能会调用或覆盖委托变量来执行不合理的操作。
因此一般来说想要创建一个包含多个类的动态方法系统使用事件变量而非委托变量。

EventManager

  1. public class EventManager : MonoBehaviour
  2. {
  3. public delegate void ClickAction();
  4. public static event ClickAction OnClicked;
  5. void OnGUI()
  6. {
  7. if(GUI.Button(new Rect(Screen.width / 2 - 50, 5, 100, 30), "Click"))
  8. {
  9. if(OnClicked != null)
  10. OnClicked();
  11. }
  12. }
  13. }

TeleportScript(小球一)

  1. public class TeleportScript : MonoBehaviour
  2. {
  3. void OnEnable()
  4. {
  5. EventManager.OnClicked += Teleport;
  6. }
  7. void OnDisable()
  8. {
  9. EventManager.OnClicked -= Teleport;
  10. }
  11. void Teleport()
  12. {
  13. Vector3 pos = transform.position;
  14. pos.y = Random.Range(1.0f, 3.0f);
  15. transform.position = pos;
  16. }
  17. }

TurnColorScript(小球二)

  1. public class TurnColorScript : MonoBehaviour
  2. {
  3. void OnEnable()
  4. {
  5. EventManager.OnClicked += TurnColor;
  6. }
  7. void OnDisable()
  8. {
  9. EventManager.OnClicked -= TurnColor;
  10. }
  11. void TurnColor()
  12. {
  13. Color col = new Color(Random.value, Random.value, Random.value);
  14. renderer.material.color = col;
  15. }
  16. }