原文地址:http://bbs.9ria.com/thread-153258-1-1.html

原project地址:https://github.com/djandrew/UnityEventManager

多年的Flash开发。我很赞赏Flash的事件系统。

Uinty对象通信所使用的方法SendMessage在多数情况下是工作正常,但假设在一个具有无数引用其它对象的GameObject的大型项目进行反射,那问题就来了。

我用C#在Uinty中所写的第一个东西,就是管理抽象类的事件管理系统。

究其核心。EventManager使用也是SendMessage。并对游戏对象[gameObject]有直接引用,但若有事件发生。其便会对需求进行分解,不同的类间会有信息共享,这样事件对象就知道怎样互相通信。

若有不论什么建议或修正。欢迎留言。

EventManager.cs(十按。本链接为凝视译版,若认为某译不妥请对比英文版自行勘误)

  1. /*
  2. Event Manager
  3. Static manager for handling an event driven communication model in Unity.
  4. This is similar to Adobe Flash's event listener model used in ActionScript.
  5. Copyright © 2012 Dustin Andrew
  6. dustin.andrew@gmail.com
  7. http://www.dustinandrew.me/
  8. This program is free software: you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation, either version 3 of the License, or
  11. any later version.
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16. http://www.gnu.org/licenses/
  17. */
  18. /*
  19. *  Setup:
  20. *  Create an empty GameObject and add the EventManager script to it.
  21. *  Create custom event classes that extend the CustomEvent.
  22. *
  23. *  Restrictions & Tips:
  24. *  DO NOT add event listeners in the Awake() method!
  25. *  This is used by the EventManager to initialize.
  26. *  Change this class' Execution Order to before default time if you need to work around this.
  27. *  Use the Start() method to setup your events.
  28. *  Make event listener callback functions public.
  29. *  Extend the CustomEvent class when creating your events.
  30. *  Use custom variables in your custom events over the arguments hashtable to maintain class abstraction
  31. *  Clean up and remove event listeners when objects are destroyed.
  32. *  Events are not received if the listener gameObject.active is false.
  33. *
  34. *  Examples:
  35. *
  36. *  // setup event listeners
  37. *  void Start() {
  38. *      EventManager.instance.addEventListener(CustomEventObj.EVENT_TO_LISTEN_TO, gameObject, "OnSomethingHappened");
  39. *  }
  40. *
  41. *  // remove event listeners
  42. *  void OnDestroy() {
  43. *      if (gameObject) {
  44. *          // remove a single event
  45. *          EventManager.instance.removeEventListener(CustomEventObj.EVENT_TO_LISTEN_TO, gameObject);
  46. *          // remove all events
  47. *          EventManager.instance.removeAllEventListeners(gameObject);
  48. *      }
  49. *  }
  50. *
  51. *  // get values passed by events
  52. *  public void OnSomethingHappened(CustomEventObj evt) {
  53. *      Debug.Log((datatype)evt.arguments["value"]);
  54. *      // or if using custom vars instead of arguments hashtable
  55. *      Debug.Log(evt.rockOn);
  56. *  }
  57. *
  58. *  // dispatch events
  59. *  void TriggerEvent() {
  60. *      CustomEventObj evt = new CustomEventObj(CustomEventObj.EVENT_TO_TRIGGER);
  61. *      evt.arguments.Add("value", 3);
  62. *      EventManager.instance.dispatchEvent(evt);
  63. *  }
  64. *
  65. *  // create custom events
  66. *  using UnityEngine;
  67. *  using System.Collections;
  68. *
  69. *  public class CustomEventObj : CustomEvent {
  70. *
  71. *      // event types
  72. *      public static string MY_EVENT_1 = "my_event_1";
  73. *      public static string MY_EVENT_2 = "my_event_2";
  74. *
  75. *      // optionally add custom variables instead of using the arguments hashtable
  76. *      public int myCustomEventVar1 = 0;
  77. *      public bool rockOn = true;
  78. *
  79. *      public CustomEventObj(string eventType = "") {
  80. *         type = eventType;
  81. *      }
  82. *  }
  83. *
  84. */
  85. using UnityEngine;
  86. using System.Collections;
  87. // internal event listener model
  88. internal class EventListener {
  89. public string name;
  90. public GameObject listener;
  91. public string function;
  92. }
  93. // Custom event class, extend when creating custom events
  94. public class CustomEvent {
  95. private string _type;
  96. private Hashtable _arguments = new Hashtable();
  97. // constructor
  98. public CustomEvent(string eventType = "") {
  99. _type = eventType;
  100. }
  101. // the type of event
  102. public string type {
  103. get { return _type; }
  104. set { _type = value; }
  105. }
  106. // the arguments to pass with the event
  107. public Hashtable arguments {
  108. get { return _arguments; }
  109. set { _arguments = value; }
  110. }
  111. }
  112. public class EventManager : MonoBehaviour {
  113. // singleton instance
  114. public static EventManager instance;
  115. // settings
  116. public bool allowSingleton = true; // EventManager class will transfer between scene changes.
  117. public bool allowWarningOutputs = true;
  118. public bool allowDebugOutputs = true;
  119. private static bool _created = false;
  120. private Hashtable _listeners = new Hashtable();
  121. // setup singleton if allowed
  122. public void Awake() {
  123. if (!_created && allowSingleton) {
  124. DontDestroyOnLoad(this);
  125. instance = this;
  126. _created = true;
  127. Setup();
  128. } else {
  129. if (allowSingleton) {
  130. if (EventManager.instance.allowWarningOutputs) {
  131. Debug.LogWarning("Only a single instance of " + this.name + " should exists!");
  132. }
  133. Destroy(gameObject);
  134. } else {
  135. instance = this;
  136. Setup();
  137. }
  138. }
  139. }
  140. // clear events on quit
  141. public void OnApplicationQuit() {
  142. _listeners.Clear();
  143. }
  144. // PUBLIC *******************************
  145. // Add event listener
  146. public bool addEventListener(string eventType, GameObject listener, string function) {
  147. if (listener == null || eventType == null) {
  148. if (allowWarningOutputs) {
  149. Debug.LogWarning("Event Manager: AddListener failed due to no listener or event name specified.");
  150. }
  151. return false;
  152. }
  153. recordEvent(eventType);
  154. return recordListener(eventType, listener, function);
  155. }
  156. // Remove event listener
  157. public bool removeEventListener(string eventType, GameObject listener) {
  158. if (!checkForEvent(eventType)) return false;
  159. ArrayList listenerList = _listeners[eventType] as ArrayList;
  160. foreach (EventListener callback in listenerList) {
  161. if (callback.name == listener.GetInstanceID().ToString()) {
  162. listenerList.Remove(callback);
  163. return true;
  164. }
  165. }
  166. return false;
  167. }
  168. // Remove all event listeners
  169. public void removeAllEventListeners(GameObject listener) {
  170. foreach (EventListener callback in _listeners) {
  171. if (callback.listener.GetInstanceID().ToString() == listener.GetInstanceID().ToString()) {
  172. _listeners.Remove(callback);
  173. }
  174. }
  175. }
  176. // Dispatch an event
  177. public bool dispatchEvent(CustomEvent evt) {
  178. string eventType = evt.type;
  179. if (!checkForEvent(eventType)) {
  180. if (allowWarningOutputs) {
  181. Debug.LogWarning("Event Manager: Event \"" + eventType + "\" triggered has no listeners!");
  182. }
  183. return false;
  184. }
  185. ArrayList listenerList = _listeners[eventType] as ArrayList;
  186. if (allowDebugOutputs) {
  187. Debug.Log("Event Manager: Event " + eventType + " dispatched to " + listenerList.Count + ((listenerList.Count == 1) ? " listener." : " listeners."));
  188. }
  189. foreach (EventListener callback in listenerList) {
  190. if (callback.listener && callback.listener.active) {
  191. callback.listener.SendMessage(callback.function, evt, SendMessageOptions.DontRequireReceiver);
  192. }
  193. }
  194. return false;
  195. }
  196. // PRIVATE *******************************
  197. private void Setup() {
  198. // TO DO: Self create GameObject if not already created
  199. }
  200. // see if event already exists
  201. private bool checkForEvent(string eventType) {
  202. if (_listeners.ContainsKey(eventType)) return true;
  203. return false;
  204. }
  205. // record event, if it doesn't already exists
  206. private bool recordEvent(string eventType) {
  207. if (!checkForEvent(eventType)) {
  208. _listeners.Add(eventType, new ArrayList());
  209. }
  210. return true;
  211. }
  212. // delete event, if not already removed
  213. private bool deleteEvent(string eventType) {
  214. if (!checkForEvent(eventType)) return false;
  215. _listeners.Remove(eventType);
  216. return true;
  217. }
  218. // check if listener exists
  219. private bool checkForListener(string eventType, GameObject listener) {
  220. if (!checkForEvent(eventType)) {
  221. recordEvent(eventType);
  222. }
  223. ArrayList listenerList = _listeners[eventType] as ArrayList;
  224. foreach (EventListener callback in listenerList) {
  225. if (callback.name == listener.GetInstanceID().ToString()) return true;
  226. }
  227. return false;
  228. }
  229. // record listener, if not already recorded
  230. private bool recordListener(string eventType, GameObject listener, string function) {
  231. if (!checkForListener(eventType, listener)) {
  232. ArrayList listenerList = _listeners[eventType] as ArrayList;
  233. EventListener callback = new EventListener();
  234. callback.name = listener.GetInstanceID().ToString();
  235. callback.listener = listener;
  236. callback.function = function;
  237. listenerList.Add(callback);
  238. return true;
  239. } else {
  240. if (allowWarningOutputs) {
  241. Debug.LogWarning("Event Manager: Listener: " + listener.name + " is already in list for event: " + eventType);
  242. }
  243. return false;
  244. }
  245. }
  246. }

复制代码

原文链接:http://www.dustinandrew.me/blog/2012/10/9/unity3d-c-event-manager.html

翻译词数:225

Unity3D C#事件管理:EventManager的更多相关文章

  1. phalcon: plugin 结合Manager事件管理、dispatcher调度控制器 监听sql日志记录或其他拦截出来

    可能用到的类 phalcon\mvc\use\plugin Phalcon\Mvc\Dispatcher as MvcDispatcher Phalcon\Events\Manager as Even ...

  2. storm事件管理器EventManager源码分析-event.clj

    storm事件管理器定义在event.clj中,主要功能就是通过独立线程执行"事件处理函数".我们可以将"事件处理函数"添加到EventManager的阻塞队列 ...

  3. zendframework 事件管理(二)

    首先需要明确的几个问题: Q1.什么是事件? A:事件就是一个有名字的行为.当这个行为发生的时候,称这个事件被触发. Q2.监听器又是什么? A:监听器决定了事件的逻辑表达,由事件触发.监听器和事件往 ...

  4. zendframework 事件管理(一)

    zend里的事件管理器主要是为了实现: 1.观察者模式 2.面向切面设计 3.事件驱动构架 事件管理最基本的功能是将监听器与事件连接或断开.不论时连接还是断开都是通过shared collection ...

  5. 自定义事件类EventManager (TS中...args的使用例子)

    一个自定义事件类 初衷是使用Egret的事件有两点比较麻烦 1   在事件处理函数时,需要从e中获取data hander(e:egret.Event){ let data = e.data; } 2 ...

  6. 服务器文档下载zip格式 SQL Server SQL分页查询 C#过滤html标签 EF 延时加载与死锁 在JS方法中返回多个值的三种方法(转载) IEnumerable,ICollection,IList接口问题 不吹不擂,你想要的Python面试都在这里了【315+道题】 基于mvc三层架构和ajax技术实现最简单的文件上传 事件管理

    服务器文档下载zip格式   刚好这次项目中遇到了这个东西,就来弄一下,挺简单的,但是前台调用的时候弄错了,浪费了大半天的时间,本人也是菜鸟一枚.开始吧.(MVC的) @using Rattan.Co ...

  7. cocos2d-js v3事件管理器

    总概: 1.时间监听器(cc.EventListener)封装用户的事件处理逻辑. 2.事件管理器(cc.eventManager)管理用户注册的事件监听器. 3.事件对象(cc.Event)包含事件 ...

  8. JavaScript 事件管理

    在设计JavaScript xxsdk的时候考虑到能让调用者参与到工作流程中来,开始用了回调函数.如下: this.foo = function(args,callbackFn) { //do som ...

  9. jquery技巧之让任何组件都支持类似DOM的事件管理

    本文介绍一个jquery的小技巧,能让任意组件对象都能支持类似DOM的事件管理,也就是说除了派发事件,添加或删除事件监听器,还能支持事件冒泡,阻止事件默认行为等等.在jquery的帮助下,使用这个方法 ...

随机推荐

  1. EffectiveJava(8)覆盖equals是要遵守的约定

    覆盖equals是要遵守的约定 1.覆盖种类: -类的每个1实例本质上都是唯一的 -不关心类是否提供了"逻辑相等"的测试功能(Random测试是否能随机相同数字) -超类已经覆盖了 ...

  2. VS中c++文件调用c 函数 ,fatal error C1853 预编译头文件来自编译器的早期版本号,或者预编译头为 C++ 而在 C 中使用它(或相反)

    出现错误:error C1853: "Debug\ConsoleApplication1.pch"预编译头文件来自编译器的早期版本号.或者预编译头为 C++ 而在 C 中使用它(或 ...

  3. 10.3.1 一个CONNECT BY的样例

    10.3.1 一个CONNECT BY的样例正在更新内容,请稍后

  4. hdu4888 多校B 最大流以及最大流唯一推断+输出方案

    题意.给一个矩阵,告诉你每行和.每列和.而且限制所填数不大于k,问矩阵是否唯一. 经典建图不说了.第一次遇到推断最大流唯一性的.学习了:用dfs来推断残网中是否还存在环,若存在,则表明绕这个环走一圈, ...

  5. Window 7 开 WIFI做热点

    cmd下两个命令即可: C:\Users\lyx>netsh wlan set hostednetwork mode=allow ssid=ACE-PC key=12345678承载网络模式已设 ...

  6. .aspx 页面引用命名空间

    一.单个页面引用: <%@ Import Namespace="" %> 二.所有页面引用,Web.config配置如下: <system.web> < ...

  7. Calculation 2-欧拉函数的运用

    Calculation 2 Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u Submit ...

  8. ASP.NET CORE RAZOR :将文件上传至 ASP.NET Core 中的 Razor 页面

    本部分演示使用 Razor 页面上传文件. 本教程中的 Razor 页面 Movie 示例应用使用简单的模型绑定上传文件,非常适合上传小型文件. 有关流式传输大文件的信息,请参阅通过流式传输上传大文件 ...

  9. eclipse / ADT(Android Develop Tool) 一些方便的初始设置

      1.设置编辑窗口的背景色eclipse的主编辑窗口的背景色,默认为白色,个人感觉太亮,推荐保护视力的“墨绿色”,当然也可以根据个人喜好更改,如下图 2.主编辑窗口的字体字号等,也可以根据自己的爱好 ...

  10. 李洪强经典面试题39-iOS 程序员 6 级考试(答案和解释)

    iOS 程序员 6 级考试(答案和解释)   我是前言 1. 下面的代码分别输出什么? @implementation Son : Father- (id)init { self = [super i ...