http://blog.csdn.net/abcdtty/article/details/13021237html
事件系統是個好東西,不只調用方便,並且能最大程度的下降系統各部分的耦合度. 網上有關這方面的東西不少不少,我也用過很多,最近發現一個比較優秀的,即快速(不用遍歷大串的方法列表)又簡潔(代碼不多). 分享上來和新手同窗們共勉.ide
具體實現以下:this
1.先定義事件參數類: EventArgs 是基類,不建議直接使用,由於通用的東西針對性不強,容易混亂(特別是找bug 的時候)... MyEvent 的具體的派生類,建議的使用方法就是每一個種類的事件派生一個類,好比UIEvent,ServerEvent神馬的,根據具體做用來命名.spa
[csharp] view plaincopyprint?.net
/// <summary> orm
/// 事件參數基類 htm
/// </summary> blog
public class EventArgs 事件
{ ip
public object Parameter;
}
/// <summary>
/// 自定義事件參數
/// </summary>
public class MyEvent : EventArgs
{
public int ID;
public string Name; // ...etc
}
/// <summary>
/// 事件參數基類
/// </summary>
public class EventArgs
{
public object Parameter;
}
/// <summary>
/// 自定義事件參數
/// </summary>
public class MyEvent : EventArgs
{
public int ID;
public string Name; // ...etc
}
2. 事件管理類: 能夠看出是一個單例類,世界各地都能直接調用. _delegates負責保存全部事件接收方法,事件被按類型存在裏面,同一個類型不管幾條記錄都只佔一個項(因此不用遍歷大串的方法列表)
[csharp] view plaincopyprint?
/// <summary>
/// 事件管理類
/// </summary>
public class EventManager
{
//單例模式.
public static readonly EventManager Instance = new EventManager();
private EventManager() { }
//事件委託.
public delegate void EventDelegate<T>(T e) where T : EventArgs;
//保存全部事件<span style="font-family: Arial,Helvetica,sans-serif;">接收方法</span>.
readonly Dictionary<Type, Delegate> _delegates = new Dictionary<Type, Delegate>();
//添加一個事件接收方法.
public void AddListener<T>(EventDelegate<T> listener) where T : EventArgs
{
Delegate d;
if (_delegates.TryGetValue(typeof(T), out d))
{
_delegates[typeof(T)] = Delegate.Combine(d, listener);
}
else
{
_delegates[typeof(T)] = listener;
}
}
//刪除一個事件接受方法
public void RemoveListener<T>(EventDelegate<T> listener) where T : EventArgs
{
Delegate d;
if (_delegates.TryGetValue(typeof(T), out d))
{
Delegate currentDel = Delegate.Remove(d, listener);
if (currentDel == null)
{
_delegates.Remove(typeof(T));
}
else
{
_delegates[typeof(T)] = currentDel;
}
}
}
//發送事件.
public void Send<T>(T e) where T : EventArgs
{
if (e == null)
{
throw new ArgumentNullException("e");
}
Delegate d;
if (_delegates.TryGetValue(typeof(T), out d))
{
EventDelegate<T> callback = d as EventDelegate<T>;
if (callback != null)
{
callback(e);
}
}
}
}
/// <summary>
/// 事件管理類
/// </summary>
public class EventManager
{
//單例模式.
public static readonly EventManager Instance = new EventManager();
private EventManager() { }
//事件委託.
public delegate void EventDelegate<T>(T e) where T : EventArgs;
//保存全部事件接收方法.
readonly Dictionary<Type, Delegate> _delegates = new Dictionary<Type, Delegate>();
//添加一個事件接收方法.
public void AddListener<T>(EventDelegate<T> listener) where T : EventArgs
{
Delegate d;
if (_delegates.TryGetValue(typeof(T), out d))
{
_delegates[typeof(T)] = Delegate.Combine(d, listener);
}
else
{
_delegates[typeof(T)] = listener;
}
}
//刪除一個事件接受方法
public void RemoveListener<T>(EventDelegate<T> listener) where T : EventArgs
{
Delegate d;
if (_delegates.TryGetValue(typeof(T), out d))
{
Delegate currentDel = Delegate.Remove(d, listener);
if (currentDel == null)
{
_delegates.Remove(typeof(T));
}
else
{
_delegates[typeof(T)] = currentDel;
}
}
}
//發送事件.
public void Send<T>(T e) where T : EventArgs
{
if (e == null)
{
throw new ArgumentNullException("e");
}
Delegate d;
if (_delegates.TryGetValue(typeof(T), out d))
{
EventDelegate<T> callback = d as EventDelegate<T>;
if (callback != null)
{
callback(e);
}
}
}
}
3. 使用示例: 使用灰常簡單,以下: 先添加一個事件接收方法(就是當事件被髮出的時候會調用的接收方法), 而後須要觸發事件時使用Send方法發送便可.
[csharp] view plaincopyprint?
/// <summary>
/// 使用示例
/// </summary>
public class Test
{
public Test()
{
//添加事件接收方法
EventManager.Instance.AddListener<MyEvent>(ReceiveEvent);
//發送MyEvent事件, 以後ReceiveEvent(MyEvent e)方法將被調用.
MyEvent e = new MyEvent(); //事件參數.
e.ID =0;
e.Name = "XOXOOX";
//事件發送
EventManager.Instance.Send<MyEvent>(e);
}
//接收MyEvent事件的方法.
public void ReceiveEvent(MyEvent e)
{
}
}
/// <summary>
/// 使用示例
/// </summary>
public class Test
{
public Test()
{
//添加事件接收方法
EventManager.Instance.AddListener<MyEvent>(ReceiveEvent);
//發送MyEvent事件, 以後ReceiveEvent(MyEvent e)方法將被調用.
MyEvent e = new MyEvent(); //事件參數.
e.ID =0;
e.Name = "XOXOOX";
//事件發送
EventManager.Instance.Send<MyEvent>(e);
}
//接收MyEvent事件的方法.
public void ReceiveEvent(MyEvent e)
{
}
}
http://www.xuebuyuan.com/1562272.html
窗體有三種:幾秒後消失的,按肯定後消失的,選擇是或者否而後消失的
一個比較簡單高效的事件系統,
EventManager.Instance.AddListener<UINotificaionArgs>(CallNotification);//註冊事件
//觸發彈窗的方法
EventManager.Instance.Send(new UINotificationArgs(){NMessageType = NMessageType.AskForYesOrNot,del = 你要執行的方法 ,Infomation = 你要顯示的信息});//這個是帶有按下肯定後執行相應方法的彈窗
EventManager.Instance.Send(new UINotificationArgs(){NMessageType = NMessageType.AskForOk,Infomation = 你要顯示的信息});//這個是沒有方法,但要你按下確認纔會消失的彈窗
EventManager.Instance.Send(new UINotificationArgs(){NMessageType = NMessageType.NoAsk,Infomation = 你要顯示的信息,WaitTime = 4f});//這個是沒有按鈕,可是會在幾秒後彈窗消失的模式
//理解了這個事件系統就容易理解原理了
//至於具體的NGUI實現,看下面的變量名稱也大約能明白了,工程無法上傳
using UnityEngine;
using System.Collections;
public class UINotificaionArgs : EventArgs {
private NMessageType nMessageType;
public NMessageType NMessageType {
get {
return nMessageType;
}
set {
nMessageType = value;
}
}
private string infomation;
public string Infomation {
get {
return infomation;
}
set {
infomation = value;
}
}
private float waitTime;
public float WaitTime {
get {
return waitTime;
}
set {
waitTime = value;
}
}
//public delegate void NotificationDel();
public DelegateManage.NotificationDel del;
}
public class DelegateManage
{
public delegate void NotificationDel();
}
public enum NMessageType
{
NoAsk,
AskForOk,
AskForYesOrNot
}
以上是事件的內容部分,傳遞三個參數,一個是彈窗的類型,一個是須要等待的時間(第一種窗體須要),一個按下肯定後執行的方法的委託
下面的是彈窗的具體管理組件
首先註冊事件
而後是根據傳遞來的事件的具體內容,執行相關的方法
最後的兩個方法是爲按鈕準備的
按下yes以後執行pressOk()
就調用了經過事件傳遞的,按下肯定後,須要執行的方法了
using UnityEngine;
using System.Collections;
public class NotifacationManager : MonoBehaviour {
public UILabel Info;
public GameObject Ask;
public GameObject AskOrNot;
private NMessageType messageType;
private float WaitTime;
private DelegateManage.NotificationDel del;
void Start()
{
EventManager.Instance.AddListener<UINotificaionArgs>(CallNotification);
}
public void DisplayWindow()
{
foreach (Transform child in this.transform) {
child.gameObject.SetActive(true);
}
}
public void HideWindow()
{
foreach (Transform child in this.transform) {
child.gameObject.SetActive(false);
}
}
private void CallNotification(UINotificaionArgs e)
{
DisplayWindow ();
Info.text = e.Infomation;
switch (e.NMessageType)
{
case NMessageType.NoAsk:
WaitTime = e.WaitTime;
StartCoroutine(NoAsk());
break;
case NMessageType.AskForOk:
del = e.del;
AskForOk();
break;
case NMessageType.AskForYesOrNot:
del = e.del;
AskOkOrNot();
break;
}
}
IEnumerator NoAsk()
{
Ask.SetActive (false);
AskOrNot.SetActive (false);
yield return new WaitForSeconds(WaitTime);
HideWindow ();
}
void AskForOk()
{
Ask.SetActive (true);
AskOrNot.SetActive (false);
}
void AskOkOrNot()
{
Ask.SetActive (false);
AskOrNot.SetActive (true);
}
public void PressOK()
{
del ();
HideWindow ();
}
public void PressNo()
{
HideWindow ();
}
}