Unity3D C#事件管理:EventManager
原文地址: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(十按。本链接为凝视译版,若认为某译不妥请对比英文版自行勘误)
- /*
- Event Manager
- Static manager for handling an event driven communication model in Unity.
- This is similar to Adobe Flash's event listener model used in ActionScript.
- Copyright © 2012 Dustin Andrew
- dustin.andrew@gmail.com
- http://www.dustinandrew.me/
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- http://www.gnu.org/licenses/
- */
- /*
- * Setup:
- * Create an empty GameObject and add the EventManager script to it.
- * Create custom event classes that extend the CustomEvent.
- *
- * Restrictions & Tips:
- * DO NOT add event listeners in the Awake() method!
- * This is used by the EventManager to initialize.
- * Change this class' Execution Order to before default time if you need to work around this.
- * Use the Start() method to setup your events.
- * Make event listener callback functions public.
- * Extend the CustomEvent class when creating your events.
- * Use custom variables in your custom events over the arguments hashtable to maintain class abstraction
- * Clean up and remove event listeners when objects are destroyed.
- * Events are not received if the listener gameObject.active is false.
- *
- * Examples:
- *
- * // setup event listeners
- * void Start() {
- * EventManager.instance.addEventListener(CustomEventObj.EVENT_TO_LISTEN_TO, gameObject, "OnSomethingHappened");
- * }
- *
- * // remove event listeners
- * void OnDestroy() {
- * if (gameObject) {
- * // remove a single event
- * EventManager.instance.removeEventListener(CustomEventObj.EVENT_TO_LISTEN_TO, gameObject);
- * // remove all events
- * EventManager.instance.removeAllEventListeners(gameObject);
- * }
- * }
- *
- * // get values passed by events
- * public void OnSomethingHappened(CustomEventObj evt) {
- * Debug.Log((datatype)evt.arguments["value"]);
- * // or if using custom vars instead of arguments hashtable
- * Debug.Log(evt.rockOn);
- * }
- *
- * // dispatch events
- * void TriggerEvent() {
- * CustomEventObj evt = new CustomEventObj(CustomEventObj.EVENT_TO_TRIGGER);
- * evt.arguments.Add("value", 3);
- * EventManager.instance.dispatchEvent(evt);
- * }
- *
- * // create custom events
- * using UnityEngine;
- * using System.Collections;
- *
- * public class CustomEventObj : CustomEvent {
- *
- * // event types
- * public static string MY_EVENT_1 = "my_event_1";
- * public static string MY_EVENT_2 = "my_event_2";
- *
- * // optionally add custom variables instead of using the arguments hashtable
- * public int myCustomEventVar1 = 0;
- * public bool rockOn = true;
- *
- * public CustomEventObj(string eventType = "") {
- * type = eventType;
- * }
- * }
- *
- */
- using UnityEngine;
- using System.Collections;
- // internal event listener model
- internal class EventListener {
- public string name;
- public GameObject listener;
- public string function;
- }
- // Custom event class, extend when creating custom events
- public class CustomEvent {
- private string _type;
- private Hashtable _arguments = new Hashtable();
- // constructor
- public CustomEvent(string eventType = "") {
- _type = eventType;
- }
- // the type of event
- public string type {
- get { return _type; }
- set { _type = value; }
- }
- // the arguments to pass with the event
- public Hashtable arguments {
- get { return _arguments; }
- set { _arguments = value; }
- }
- }
- public class EventManager : MonoBehaviour {
- // singleton instance
- public static EventManager instance;
- // settings
- public bool allowSingleton = true; // EventManager class will transfer between scene changes.
- public bool allowWarningOutputs = true;
- public bool allowDebugOutputs = true;
- private static bool _created = false;
- private Hashtable _listeners = new Hashtable();
- // setup singleton if allowed
- public void Awake() {
- if (!_created && allowSingleton) {
- DontDestroyOnLoad(this);
- instance = this;
- _created = true;
- Setup();
- } else {
- if (allowSingleton) {
- if (EventManager.instance.allowWarningOutputs) {
- Debug.LogWarning("Only a single instance of " + this.name + " should exists!");
- }
- Destroy(gameObject);
- } else {
- instance = this;
- Setup();
- }
- }
- }
- // clear events on quit
- public void OnApplicationQuit() {
- _listeners.Clear();
- }
- // PUBLIC *******************************
- // Add event listener
- public bool addEventListener(string eventType, GameObject listener, string function) {
- if (listener == null || eventType == null) {
- if (allowWarningOutputs) {
- Debug.LogWarning("Event Manager: AddListener failed due to no listener or event name specified.");
- }
- return false;
- }
- recordEvent(eventType);
- return recordListener(eventType, listener, function);
- }
- // Remove event listener
- public bool removeEventListener(string eventType, GameObject listener) {
- if (!checkForEvent(eventType)) return false;
- ArrayList listenerList = _listeners[eventType] as ArrayList;
- foreach (EventListener callback in listenerList) {
- if (callback.name == listener.GetInstanceID().ToString()) {
- listenerList.Remove(callback);
- return true;
- }
- }
- return false;
- }
- // Remove all event listeners
- public void removeAllEventListeners(GameObject listener) {
- foreach (EventListener callback in _listeners) {
- if (callback.listener.GetInstanceID().ToString() == listener.GetInstanceID().ToString()) {
- _listeners.Remove(callback);
- }
- }
- }
- // Dispatch an event
- public bool dispatchEvent(CustomEvent evt) {
- string eventType = evt.type;
- if (!checkForEvent(eventType)) {
- if (allowWarningOutputs) {
- Debug.LogWarning("Event Manager: Event \"" + eventType + "\" triggered has no listeners!");
- }
- return false;
- }
- ArrayList listenerList = _listeners[eventType] as ArrayList;
- if (allowDebugOutputs) {
- Debug.Log("Event Manager: Event " + eventType + " dispatched to " + listenerList.Count + ((listenerList.Count == 1) ? " listener." : " listeners."));
- }
- foreach (EventListener callback in listenerList) {
- if (callback.listener && callback.listener.active) {
- callback.listener.SendMessage(callback.function, evt, SendMessageOptions.DontRequireReceiver);
- }
- }
- return false;
- }
- // PRIVATE *******************************
- private void Setup() {
- // TO DO: Self create GameObject if not already created
- }
- // see if event already exists
- private bool checkForEvent(string eventType) {
- if (_listeners.ContainsKey(eventType)) return true;
- return false;
- }
- // record event, if it doesn't already exists
- private bool recordEvent(string eventType) {
- if (!checkForEvent(eventType)) {
- _listeners.Add(eventType, new ArrayList());
- }
- return true;
- }
- // delete event, if not already removed
- private bool deleteEvent(string eventType) {
- if (!checkForEvent(eventType)) return false;
- _listeners.Remove(eventType);
- return true;
- }
- // check if listener exists
- private bool checkForListener(string eventType, GameObject listener) {
- if (!checkForEvent(eventType)) {
- recordEvent(eventType);
- }
- ArrayList listenerList = _listeners[eventType] as ArrayList;
- foreach (EventListener callback in listenerList) {
- if (callback.name == listener.GetInstanceID().ToString()) return true;
- }
- return false;
- }
- // record listener, if not already recorded
- private bool recordListener(string eventType, GameObject listener, string function) {
- if (!checkForListener(eventType, listener)) {
- ArrayList listenerList = _listeners[eventType] as ArrayList;
- EventListener callback = new EventListener();
- callback.name = listener.GetInstanceID().ToString();
- callback.listener = listener;
- callback.function = function;
- listenerList.Add(callback);
- return true;
- } else {
- if (allowWarningOutputs) {
- Debug.LogWarning("Event Manager: Listener: " + listener.name + " is already in list for event: " + eventType);
- }
- return false;
- }
- }
- }
复制代码
原文链接:http://www.dustinandrew.me/blog/2012/10/9/unity3d-c-event-manager.html
翻译词数:225
Unity3D C#事件管理:EventManager的更多相关文章
- phalcon: plugin 结合Manager事件管理、dispatcher调度控制器 监听sql日志记录或其他拦截出来
可能用到的类 phalcon\mvc\use\plugin Phalcon\Mvc\Dispatcher as MvcDispatcher Phalcon\Events\Manager as Even ...
- storm事件管理器EventManager源码分析-event.clj
storm事件管理器定义在event.clj中,主要功能就是通过独立线程执行"事件处理函数".我们可以将"事件处理函数"添加到EventManager的阻塞队列 ...
- zendframework 事件管理(二)
首先需要明确的几个问题: Q1.什么是事件? A:事件就是一个有名字的行为.当这个行为发生的时候,称这个事件被触发. Q2.监听器又是什么? A:监听器决定了事件的逻辑表达,由事件触发.监听器和事件往 ...
- zendframework 事件管理(一)
zend里的事件管理器主要是为了实现: 1.观察者模式 2.面向切面设计 3.事件驱动构架 事件管理最基本的功能是将监听器与事件连接或断开.不论时连接还是断开都是通过shared collection ...
- 自定义事件类EventManager (TS中...args的使用例子)
一个自定义事件类 初衷是使用Egret的事件有两点比较麻烦 1 在事件处理函数时,需要从e中获取data hander(e:egret.Event){ let data = e.data; } 2 ...
- 服务器文档下载zip格式 SQL Server SQL分页查询 C#过滤html标签 EF 延时加载与死锁 在JS方法中返回多个值的三种方法(转载) IEnumerable,ICollection,IList接口问题 不吹不擂,你想要的Python面试都在这里了【315+道题】 基于mvc三层架构和ajax技术实现最简单的文件上传 事件管理
服务器文档下载zip格式 刚好这次项目中遇到了这个东西,就来弄一下,挺简单的,但是前台调用的时候弄错了,浪费了大半天的时间,本人也是菜鸟一枚.开始吧.(MVC的) @using Rattan.Co ...
- cocos2d-js v3事件管理器
总概: 1.时间监听器(cc.EventListener)封装用户的事件处理逻辑. 2.事件管理器(cc.eventManager)管理用户注册的事件监听器. 3.事件对象(cc.Event)包含事件 ...
- JavaScript 事件管理
在设计JavaScript xxsdk的时候考虑到能让调用者参与到工作流程中来,开始用了回调函数.如下: this.foo = function(args,callbackFn) { //do som ...
- jquery技巧之让任何组件都支持类似DOM的事件管理
本文介绍一个jquery的小技巧,能让任意组件对象都能支持类似DOM的事件管理,也就是说除了派发事件,添加或删除事件监听器,还能支持事件冒泡,阻止事件默认行为等等.在jquery的帮助下,使用这个方法 ...
随机推荐
- EffectiveJava(8)覆盖equals是要遵守的约定
覆盖equals是要遵守的约定 1.覆盖种类: -类的每个1实例本质上都是唯一的 -不关心类是否提供了"逻辑相等"的测试功能(Random测试是否能随机相同数字) -超类已经覆盖了 ...
- VS中c++文件调用c 函数 ,fatal error C1853 预编译头文件来自编译器的早期版本号,或者预编译头为 C++ 而在 C 中使用它(或相反)
出现错误:error C1853: "Debug\ConsoleApplication1.pch"预编译头文件来自编译器的早期版本号.或者预编译头为 C++ 而在 C 中使用它(或 ...
- 10.3.1 一个CONNECT BY的样例
10.3.1 一个CONNECT BY的样例正在更新内容,请稍后
- hdu4888 多校B 最大流以及最大流唯一推断+输出方案
题意.给一个矩阵,告诉你每行和.每列和.而且限制所填数不大于k,问矩阵是否唯一. 经典建图不说了.第一次遇到推断最大流唯一性的.学习了:用dfs来推断残网中是否还存在环,若存在,则表明绕这个环走一圈, ...
- Window 7 开 WIFI做热点
cmd下两个命令即可: C:\Users\lyx>netsh wlan set hostednetwork mode=allow ssid=ACE-PC key=12345678承载网络模式已设 ...
- .aspx 页面引用命名空间
一.单个页面引用: <%@ Import Namespace="" %> 二.所有页面引用,Web.config配置如下: <system.web> < ...
- Calculation 2-欧拉函数的运用
Calculation 2 Time Limit: 1000MS Memory Limit: 32768KB 64bit IO Format: %I64d & %I64u Submit ...
- ASP.NET CORE RAZOR :将文件上传至 ASP.NET Core 中的 Razor 页面
本部分演示使用 Razor 页面上传文件. 本教程中的 Razor 页面 Movie 示例应用使用简单的模型绑定上传文件,非常适合上传小型文件. 有关流式传输大文件的信息,请参阅通过流式传输上传大文件 ...
- eclipse / ADT(Android Develop Tool) 一些方便的初始设置
1.设置编辑窗口的背景色eclipse的主编辑窗口的背景色,默认为白色,个人感觉太亮,推荐保护视力的“墨绿色”,当然也可以根据个人喜好更改,如下图 2.主编辑窗口的字体字号等,也可以根据自己的爱好 ...
- 李洪强经典面试题39-iOS 程序员 6 级考试(答案和解释)
iOS 程序员 6 级考试(答案和解释) 我是前言 1. 下面的代码分别输出什么? @implementation Son : Father- (id)init { self = [super i ...