A Type-Safe Event System for Unity3D
来源:互联网 发布:雅思阅读怎样提高知乎 编辑:程序博客网 时间:2024/06/05 04:07
转载自:http://www.willrmiller.com/?p=87
The Event Listener pattern is an extremely common design pattern. Using Events instead of method calls let an object communicate with another object (or many objects) without explicit knowledge of the other object. With events acting as an implicit interface between objects, we can write much more loosely coupled (thus more reusable) code.
Unity’s own message passing system can be leveraged to achieve this effect, but there are a few problems with it. First, sending messages is hierarchy-dependent. You either need a reference to the object you wish to send the message (event) to, or you need a reference to that object’s parent object. This is not loosely coupled. Secondly, it’s not statically type-safe.
There have been several solutions to this problem (for example, FlashBang’s messaging system or this one on the UnifyCommunity wiki). These still lack type-safety, and won’t quite do.
Here is my event system implementation. It looks quite a bit like the event system in AS3:
using UnityEngine;using System.Collections;using System.Collections.Generic;public class GameEvent{}public class Events{ private static Events eventsInstance = null; public static Events instance { get { if (eventsInstance == null) { eventsInstance = new Events(); } return eventsInstance; } } public delegate void EventDelegate<T> (T e) where T : GameEvent; private Dictionary<System.Type, System.Delegate> delegates = new Dictionary<System.Type, System.Delegate>(); public void AddListener<T> (EventDelegate<T> del) where T : GameEvent { if (delegates.ContainsKey(typeof(T))) { System.Delegate tempDel = delegates[typeof(T)]; delegates[typeof(T)] = System.Delegate.Combine(tempDel, del); } else { delegates[typeof(T)] = del; } } public void RemoveListener<T> (EventDelegate<T> del) where T : GameEvent { if (delegates.ContainsKey(typeof(T))) { var currentDel = System.Delegate.Remove(delegates[typeof(T)], del); if (currentDel == null) { delegates.Remove(typeof(T)); } else { delegates[typeof(T)] = currentDel; } } } public void Raise (GameEvent e) { if (e == null) { Debug.Log("Invalid event argument: " + e.GetType().ToString()); return; } if (delegates.ContainsKey(e.GetType())) { delegates[e.GetType()].DynamicInvoke(e); } }}
To use this thing, first we declare a GameEvent subclass. This event can carry with it all of the parameters needed by the objects listening for the event.
public class SomethingHappenedEvent : GameEvent{ // Add event parameters here}
Registering to listen for the event looks like this:
public class SomeObject : MonoBehaviour{ void OnEnable () { Events.instance.AddListener<SomethingHappenedEvent>(OnSomethingHappened); } void OnDisable () { Events.instance.RemoveListener<SomethingHappenedEvent>(OnSomethingHappened); } void OnSomethingHappened (SomethingHappenedEvent e) { // Handle event here }}
And finally, to raise the event, do this:
Events.instance.Raise(new SomethingHappenedEvent());
The cool thing about this implementation is that it’s type-safe (listener registration errors will be caught at compile time, and no casting of events or event arguments) and it doesn’t require listening objects to implement a special interface or use Unity’s built-in message passing system.
The interface for this system is almost identical to that presented by Mike Mittleman at Unite 08, and I’d wager our implementations are similar. If you really want a rundown of the benefits and pitfalls of event-driven Unity development, I suggest watching his presentation on Unity’s website.
- A Type-Safe Event System for Unity3D
- A Type-Safe Event System for Unity3D
- Retrofit A type-safe HTTP client for Android and Java
- Retrofit A type-safe HTTP client for Android and Java
- Retrofit——A type-safe HTTP client for Android and Java(The first part)
- [Unity3D]uLua中类似Unity3D C# Messager的Event System
- A sample for COM Event
- 软件优才夏令营A decentralized approach for mining event correlations in distributed system monitoring译文(原创)
- Java interface & type safe
- A scripting for rebooting system
- A scripting for rebooting system
- A scripting for rebooting system
- A scripting for rebooting system
- A scripting for rebooting system
- A scripting for rebooting system
- A scripting for rebooting system
- A scripting for rebooting system
- A scripting for rebooting system
- Laravel 学习笔记 —— 神奇的服务容器
- Linux系统中校验下载文件的完整性方法(MD5,SHA1,PGP)
- Mybatis学习(五)mybatis环境下以接口的方式进行的增删查改
- 关于const char *s和char * const s
- 认识自己——趋利避害生活的能力
- A Type-Safe Event System for Unity3D
- P268 1
- HOG特征—简介
- Laravel查看当前已有的路由信息
- Android的selector,背景选择器 以及.9.png
- 各种在线手册
- P269 2
- python解析pcap文件中的http数据包
- 黑马程序员——while、do...while、for循环