Unity 之事件系统
游戏开发过程中事件是非常多的,可以通过 Messenger 事件系统来解藕,用法如下:
使用方法 例子:在按下拍照按钮后通知刷新好友面板
步骤1、添加事件字段,该字段具有唯一性
在MessangerEventDef脚本(可以每个功能都有一个事件字段脚本,类似于消息)中添加字段"Demo_EventType". 步骤2、广播事件:在按下拍照按钮方法中调用
Messenger.Broadcast(MessangerEventDef.Demo_EventType); 步骤3、在OnEnable()方法中注册事件:在FriendUI_Ctrl中的OnEnable方法中添加
Messenger.AddListener(MessangerEventDef.Demo_EventType, OnCall); 步骤4、在OnDisable()方法中移除事件:在FriendUI_Ctrl中的OnDisable方法中添加
Messenger.RemoveListener(MessangerEventDef.Demo_EventType, OnCall); void OnCall()
{
Debug.LogError("===OnCall==");
//TODO 刷新好友相关代码
} 注意事项
、AddListener和RemoveListener必须成对出现。
代码如下:
// Messenger.cs v1.0 by Magnus Wolffelt, magnus.wolffelt@gmail.com
//
// Inspired by and based on Rod Hyde's Messenger:
// http://www.unifycommunity.com/wiki/index.php?title=CSharpMessenger
//
// This is a C# messenger (notification center). It uses delegates
// and generics to provide type-checked messaging between event producers and
// event consumers, without the need for producers or consumers to be aware of
// each other. The major improvement from Hyde's implementation is that
// there is more extensive error detection, preventing silent bugs.
//
// Usage example:
// Messenger<float>.AddListener("myEvent", MyEventHandler);
// ...
// Messenger<float>.Broadcast("myEvent", 1.0f); using System;
using System.Collections.Generic; namespace Common.Messenger
{
public enum MessengerMode : byte
{
DONT_REQUIRE_LISTENER,
REQUIRE_LISTENER,
} static internal class MessengerInternal
{
static public Dictionary<string, Delegate> eventTable = new Dictionary<string, Delegate>();
static public readonly MessengerMode DEFAULT_MODE = MessengerMode.DONT_REQUIRE_LISTENER; static public void OnListenerAdding(string eventType, Delegate listenerBeingAdded)
{
if (!eventTable.ContainsKey(eventType))
{
eventTable.Add(eventType, null);
} Delegate d = eventTable[eventType];
if (d != null && d.GetType() != listenerBeingAdded.GetType())
{
throw new ListenerException(string.Format("Attempting to add listener with inconsistent signature for event type {0}. Current listeners have type {1} and listener being added has type {2}", eventType, d.GetType().Name, listenerBeingAdded.GetType().Name));
}
} static public void OnListenerRemoving(string eventType, Delegate listenerBeingRemoved)
{
if (eventTable.ContainsKey(eventType))
{
Delegate d = eventTable[eventType]; if (d == null)
{
throw new ListenerException(string.Format("Attempting to remove listener with for event type {0} but current listener is null.", eventType));
}
else if (d.GetType() != listenerBeingRemoved.GetType())
{
throw new ListenerException(string.Format("Attempting to remove listener with inconsistent signature for event type {0}. Current listeners have type {1} and listener being removed has type {2}", eventType, d.GetType().Name, listenerBeingRemoved.GetType().Name));
}
}
else
{
throw new ListenerException(string.Format("Attempting to remove listener for type {0} but Messenger doesn't know about this event type.", eventType));
}
} static public void OnListenerRemoved(string eventType)
{
if (eventTable[eventType] == null)
{
eventTable.Remove(eventType);
}
} static public void OnBroadcasting(string eventType, MessengerMode mode)
{
if (mode == MessengerMode.REQUIRE_LISTENER && !eventTable.ContainsKey(eventType))
{
throw new MessengerInternal.BroadcastException(string.Format("Broadcasting message {0} but no listener found.", eventType));
}
} static public BroadcastException CreateBroadcastSignatureException(string eventType)
{
return new BroadcastException(string.Format("Broadcasting message {0} but listeners have a different signature than the broadcaster.", eventType));
} public class BroadcastException : Exception
{
public BroadcastException(string msg)
: base(msg)
{
}
} public class ListenerException : Exception
{
public ListenerException(string msg)
: base(msg)
{
}
}
} // No parameters
static public class Messenger
{
private static Dictionary<string, Delegate> eventTable = MessengerInternal.eventTable; static public void AddListener(string eventType, Callback handler)
{
MessengerInternal.OnListenerAdding(eventType, handler);
eventTable[eventType] = (Callback)eventTable[eventType] + handler;
} static public void RemoveListener(string eventType, Callback handler)
{
MessengerInternal.OnListenerRemoving(eventType, handler);
eventTable[eventType] = (Callback)eventTable[eventType] - handler;
MessengerInternal.OnListenerRemoved(eventType);
} static public void Broadcast(string eventType)
{
Broadcast(eventType, MessengerInternal.DEFAULT_MODE);
} static public void Broadcast(string eventType, MessengerMode mode)
{
MessengerInternal.OnBroadcasting(eventType, mode);
Delegate d;
if (eventTable.TryGetValue(eventType, out d))
{
Callback callback = d as Callback;
if (callback != null)
{
callback();
}
else
{
throw MessengerInternal.CreateBroadcastSignatureException(eventType);
}
}
}
} // One parameter
static public class Messenger<T>
{
private static Dictionary<string, Delegate> eventTable = MessengerInternal.eventTable; static public void AddListener(string eventType, Callback<T> handler)
{
MessengerInternal.OnListenerAdding(eventType, handler);
eventTable[eventType] = (Callback<T>)eventTable[eventType] + handler;
} static public void RemoveListener(string eventType, Callback<T> handler)
{
MessengerInternal.OnListenerRemoving(eventType, handler);
eventTable[eventType] = (Callback<T>)eventTable[eventType] - handler;
MessengerInternal.OnListenerRemoved(eventType);
} static public void Broadcast(string eventType, T arg1)
{
Broadcast(eventType, arg1, MessengerInternal.DEFAULT_MODE);
} static public void Broadcast(string eventType, T arg1, MessengerMode mode)
{
MessengerInternal.OnBroadcasting(eventType, mode);
Delegate d;
if (eventTable.TryGetValue(eventType, out d))
{
Callback<T> callback = d as Callback<T>;
if (callback != null)
{
callback(arg1);
}
else
{
throw MessengerInternal.CreateBroadcastSignatureException(eventType);
}
}
}
} // Two parameters
static public class Messenger<T, U>
{
private static Dictionary<string, Delegate> eventTable = MessengerInternal.eventTable; static public void AddListener(string eventType, Callback<T, U> handler)
{
MessengerInternal.OnListenerAdding(eventType, handler);
eventTable[eventType] = (Callback<T, U>)eventTable[eventType] + handler;
} static public void RemoveListener(string eventType, Callback<T, U> handler)
{
MessengerInternal.OnListenerRemoving(eventType, handler);
eventTable[eventType] = (Callback<T, U>)eventTable[eventType] - handler;
MessengerInternal.OnListenerRemoved(eventType);
} static public void Broadcast(string eventType, T arg1, U arg2)
{
Broadcast(eventType, arg1, arg2, MessengerInternal.DEFAULT_MODE);
} static public void Broadcast(string eventType, T arg1, U arg2, MessengerMode mode)
{
MessengerInternal.OnBroadcasting(eventType, mode);
Delegate d;
if (eventTable.TryGetValue(eventType, out d))
{
Callback<T, U> callback = d as Callback<T, U>;
if (callback != null)
{
callback(arg1, arg2);
}
else
{
throw MessengerInternal.CreateBroadcastSignatureException(eventType);
}
}
}
} // Three parameters
static public class Messenger<T, U, V>
{
private static Dictionary<string, Delegate> eventTable = MessengerInternal.eventTable; static public void AddListener(string eventType, Callback<T, U, V> handler)
{
MessengerInternal.OnListenerAdding(eventType, handler);
eventTable[eventType] = (Callback<T, U, V>)eventTable[eventType] + handler;
} static public void RemoveListener(string eventType, Callback<T, U, V> handler)
{
MessengerInternal.OnListenerRemoving(eventType, handler);
eventTable[eventType] = (Callback<T, U, V>)eventTable[eventType] - handler;
MessengerInternal.OnListenerRemoved(eventType);
} static public void Broadcast(string eventType, T arg1, U arg2, V arg3)
{
Broadcast(eventType, arg1, arg2, arg3, MessengerInternal.DEFAULT_MODE);
} static public void Broadcast(string eventType, T arg1, U arg2, V arg3, MessengerMode mode)
{
MessengerInternal.OnBroadcasting(eventType, mode);
Delegate d;
if (eventTable.TryGetValue(eventType, out d))
{
Callback<T, U, V> callback = d as Callback<T, U, V>;
if (callback != null)
{
callback(arg1, arg2, arg3);
}
else
{
throw MessengerInternal.CreateBroadcastSignatureException(eventType);
}
}
}
} // Four parameters
static public class Messenger<T, U, V, W>
{
private static Dictionary<string, Delegate> eventTable = MessengerInternal.eventTable; static public void AddListener(string eventType, Callback<T, U, V, W> handler)
{
MessengerInternal.OnListenerAdding(eventType, handler);
eventTable[eventType] = (Callback<T, U, V, W>)eventTable[eventType] + handler;
} static public void RemoveListener(string eventType, Callback<T, U, V, W> handler)
{
MessengerInternal.OnListenerRemoving(eventType, handler);
eventTable[eventType] = (Callback<T, U, V, W>)eventTable[eventType] - handler;
MessengerInternal.OnListenerRemoved(eventType);
} static public void Broadcast(string eventType, T arg1, U arg2, V arg3, W arg4)
{
Broadcast(eventType, arg1, arg2, arg3, arg4, MessengerInternal.DEFAULT_MODE);
} static public void Broadcast(string eventType, T arg1, U arg2, V arg3, W arg4, MessengerMode mode)
{
MessengerInternal.OnBroadcasting(eventType, mode);
Delegate d;
if (eventTable.TryGetValue(eventType, out d))
{
Callback<T, U, V, W> callback = d as Callback<T, U, V, W>;
if (callback != null)
{
callback(arg1, arg2, arg3, arg4);
}
else
{
throw MessengerInternal.CreateBroadcastSignatureException(eventType);
}
}
}
} // Five parameters
static public class Messenger<T, U, V, W, X>
{
private static Dictionary<string, Delegate> eventTable = MessengerInternal.eventTable; static public void AddListener(string eventType, Callback<T, U, V, W, X> handler)
{
MessengerInternal.OnListenerAdding(eventType, handler);
eventTable[eventType] = (Callback<T, U, V, W, X>)eventTable[eventType] + handler;
} static public void RemoveListener(string eventType, Callback<T, U, V, W, X> handler)
{
MessengerInternal.OnListenerRemoving(eventType, handler);
eventTable[eventType] = (Callback<T, U, V, W, X>)eventTable[eventType] - handler;
MessengerInternal.OnListenerRemoved(eventType);
} static public void Broadcast(string eventType, T arg1, U arg2, V arg3, W arg4, X arg5)
{
Broadcast(eventType, arg1, arg2, arg3, arg4, arg5, MessengerInternal.DEFAULT_MODE);
} static public void Broadcast(string eventType, T arg1, U arg2, V arg3, W arg4, X arg5, MessengerMode mode)
{
MessengerInternal.OnBroadcasting(eventType, mode);
Delegate d;
if (eventTable.TryGetValue(eventType, out d))
{
Callback<T, U, V, W, X> callback = d as Callback<T, U, V, W, X>;
if (callback != null)
{
callback(arg1, arg2, arg3, arg4, arg5);
}
else
{
throw MessengerInternal.CreateBroadcastSignatureException(eventType);
}
}
}
} // Six parameters
static public class Messenger<T, U, V, W, X, Y>
{
private static Dictionary<string, Delegate> eventTable = MessengerInternal.eventTable; static public void AddListener(string eventType, Callback<T, U, V, W, X, Y> handler)
{
MessengerInternal.OnListenerAdding(eventType, handler);
eventTable[eventType] = (Callback<T, U, V, W, X, Y>)eventTable[eventType] + handler;
} static public void RemoveListener(string eventType, Callback<T, U, V, W, X, Y> handler)
{
MessengerInternal.OnListenerRemoving(eventType, handler);
eventTable[eventType] = (Callback<T, U, V, W, X, Y>)eventTable[eventType] - handler;
MessengerInternal.OnListenerRemoved(eventType);
} static public void Broadcast(string eventType, T arg1, U arg2, V arg3, W arg4, X arg5, Y arg6)
{
Broadcast(eventType, arg1, arg2, arg3, arg4, arg5, arg6, MessengerInternal.DEFAULT_MODE);
} static public void Broadcast(string eventType, T arg1, U arg2, V arg3, W arg4, X arg5, Y arg6, MessengerMode mode)
{
MessengerInternal.OnBroadcasting(eventType, mode);
Delegate d;
if (eventTable.TryGetValue(eventType, out d))
{
Callback<T, U, V, W, X, Y> callback = d as Callback<T, U, V, W, X, Y>;
if (callback != null)
{
callback(arg1, arg2, arg3, arg4, arg5, arg6);
}
else
{
throw MessengerInternal.CreateBroadcastSignatureException(eventType);
}
}
}
}
}
Messenger
// MessengerUnitTest.cs v1.0 by Magnus Wolffelt, magnus.wolffelt@gmail.com
//
// Delegates used in Messenger.cs.
namespace Common.Messenger
{
public delegate void Callback();
public delegate void Callback<T>(T arg1);
public delegate void Callback<T, U>(T arg1, U arg2);
public delegate void Callback<T, U, V>(T arg1, U arg2, V arg3);
public delegate void Callback<T, U, V, W>(T arg1, U arg2, V arg3, W arg4);
public delegate void Callback<T, U, V, W, X>(T arg1, U arg2, V arg3, W arg4, X arg5);
public delegate void Callback<T, U, V, W, X, Y>(T arg1, U arg2, V arg3, W arg4, X arg5, Y arg6); public delegate T CallbackReturn<T>();
public delegate T CallbackReturn<T, U>(U arg1);
}
Callback
namespace Common.Messenger
{
/// <summary>
/// This class is used to define all eventId.
/// Event string must be different.
/// </summary>
public class MessengerEventDef
{ }
}
MessengerEventDef
转载请注明出处:https://www.cnblogs.com/jietian331/p/11003386.html
Unity 之事件系统的更多相关文章
- Unity3d项目入门之虚拟摇杆
Unity本身不提供摇杆的组件,开发者可以使用牛逼的EasyTouch插件或者应用NGUI实现相关的需求,下面本文通过Unity自身的UGUI属性,实现虚拟摇杆的功能. 主参考 <Unity:使 ...
- [Unity3D] 04 - Event Manager
message消息管理 脚本与GameObject的关系 被显式添加到 Hierarchy 中的 GameObject 会被最先实例化,GameObject 被实例化的顺序是从下往上. GameObj ...
- Unity事件系统
# 1.前言Unity中事件/委托有着广泛的应用,本文通过封装一个简易的事件的系统,来统一管理消息的传递.此功能在简易应用或者事件较少的体现不出太好的作用,但是对于事件应用较多时,可以减少脚本之间的耦 ...
- Unity事件系统EventSystem简析
相关组件和类 EventSystem 1.负责InputModule的切换(因为现在游戏大部分都只有一个StanaloneInputModule,所以切换这部分可以先不考虑). 2.负责InputMo ...
- Unity开发心路历程——制作画板
有人说 编程是份很无聊的工作 因为整个工作时间面对的都是电脑这种机器 因为眼睛盯着的内容都是索然无味的代码 因为总是会有意想不到的bug让你怀疑自己的智商 而我认为 编程是件及其有意思的事情 可观的收 ...
- Unity 4.6 uGUI的点击事件
因为Unity 4.6刚刚发布,自带的uGUI功能的相关资料还不是很完善,今天刚装的Unity 4.6,想看一下uGUI是否好用,那么开始就今天的学习吧啊! 1,新建一个空的工程.
- Unity GUI选择与评价
因为Unity内建的GUI不管是不是从开发效率或效率强制,因此,许多派生GUI插入,什么插件的选择,是一个非常值它被认为是. 既然是评价,就会有非常多的主观意识,这不一定成为选择的根据. 再比方.我已 ...
- Unity For Android Cardboard App ( 1 ):基础入门
作者: ericzwhuang 前言 目前Google官方推出的VR设备有DayDream(2016年推出)和Cardboard(2014年推出)两种. Daydream是消费级VR解决方案,提供了手 ...
- 【Unity与23种设计模式】观察者模式(Observer)
GoF中定义: "在对象之间定义一个一对多的连接方法,当一个对象变换状态时,其他关联的对象都会自动收到通知." 现实中,社交网络就是个例子. 以前的报社,每次出新刊的时候, 报刊便 ...
随机推荐
- AcWing 286. 选课 (树形依赖分组背包)打卡
有依赖的背包 首先依赖的概念,就是一个东西依附与一个东西之上,我们想买附品的话必须要把主品先买下来,这个可以先做下这道题 https://www.cnblogs.com/Lis-/p/11047466 ...
- bzoj1211树的计数 x bzoj1005明明的烦恼 题解(Prufer序列)
1211: [HNOI2004]树的计数 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3432 Solved: 1295[Submit][Stat ...
- SDOI2017 树点染色
\[SDOI2017 树点染色\] 题目描述 Bob 有一棵 $ n $ 个点的有根树,其中 $ 1 $ 号点是根节点.Bob 在每个节点上涂了颜色,并且每个点上的颜色不同. 定义一条路径的权值是,这 ...
- es批量索引
使用Python操作Elasticsearch数据索引的教程 这篇文章主要介绍了使用Python操作Elasticsearch数据索引的教程,Elasticsearch处理数据索引非常高效,要的朋友可 ...
- robotframework悬浮菜单定位问题
有些菜单是悬浮菜单,鼠标点上去下级元素才会显示.比如在第一个菜单中选择后会触发二级菜单的某事件,触发二级菜单又去点三级菜单.. 最开始就用click element去点击了,可是菜单会缩回去,就有 ...
- python_way day15 HTML-DAY2、 回顾HTML-CSS 标签(css强制生效),JS(数据类型,时间处理,作用域)
python_way day15 HTML-DAY2 html-css回顾 javascript 一.html-css回顾 增加默认值: . 强制生效,就算在上面,被覆盖上了也会生效 解决缩小页面混乱 ...
- 31. Flexible static memory controller (FSMC)
31.1 FSMC main features FSMC块能够与同步和异步内存和16位PC存储卡.其主要目的是: 将AHB事务转换为适当的外部设备协议 满足外部设备的访问定时要求 所有外部存储器与控制 ...
- POJ 3304 Segments (判断直线与线段相交)
题目链接:POJ 3304 Problem Description Given n segments in the two dimensional space, write a program, wh ...
- 【二叉树】二叉树常用算法的C++实现
常见算法有: 1.求二叉树的最大深度 2.求二叉树的最小深度 3.二叉树的层次遍历 4.二叉树的前序遍历 5.二叉树的中序遍历 6.二叉树的后序遍历 7.求二叉树的节点个数 8.求二叉树的叶节点个数 ...
- 【react】---Hooks的基本使用---【巷子】
一.react-hooks概念 React中一切皆为组件,React中组件分为类组件和函数组件,在React中如果需要记录一个组件的状态的时候,那么这个组件必须是类组件.那么能否让函数组件拥有类组件的 ...