此元件作者為我的好友 - 華仔(聖淨之風),
他為了讓更多人能使用這個簡潔方便的事件處理器,就由我在此跟大家分享囉!
使用方式很簡單,只要將這兩個元件檔案<EventSender.cs>和<EventSenderT.cs>
放在Unity專案下即可,不必掛到場景物件上。
亦可使用在Unity以外的C#專案中。
<EventSender> - 用來發佈不含參數的事件
using UnityEngine; using System; using System.Collections; public class EventSender { public delegate void PubEventHandler(); //定義委託 private event PubEventHandler onPublish; //定義事件訪問器 /// <summary>事件發佈</summary> public void DoSomething () { PubEventHandler handler = onPublish; //防止多緒錯誤 if (handler != null) handler(); } /// <summary>訂閱事件</summary> /// <param name='in_onEvent'>觸發事件函式</param> public void Register (PubEventHandler in_onEvent) { onPublish += in_onEvent; } /// <summary>解除訂閱</summary> /// <param name='in_onEvent'>觸發事件函式</param> public void UnRegister (PubEventHandler in_onEvent) { onPublish -= in_onEvent; } }
<EventSenderT> - 用來發佈包含參數的事件
(參數可以是任意類型,也可以自定義一個class,在其中包許多參數)
using UnityEngine; using System; using System.Collections; public class EventSenderT<T> { public delegate void PubEventHandler(T e); //定義委託 private event PubEventHandler onPublish; //定義事件訪問器 /// <summary>事件發佈</summary> public void DoSomething (T e) { PubEventHandler handler = onPublish; //防止多緒錯誤 if (handler != null) handler(e); } /// <summary>訂閱事件</summary> /// <param name='in_onEvent'>觸發事件函式</param> public void Register (PubEventHandler in_onEvent) { onPublish += in_onEvent; } /// <summary>解除訂閱</summary> /// <param name='in_onEvent'>觸發事件函式</param> public void UnRegister (PubEventHandler in_onEvent) { onPublish -= in_onEvent; } }
當要發佈事件時,首先要宣告事件,
例如假設我們在這支程式<ButtonArthur>中宣告兩種事件,
然後把<ButtonArthur>掛在場景中的一個Cube物件上
(Unity -> GameObject -> Create Other -> Cube):
using UnityEngine; using System.Collections; public class ButtonArthur : MonoBehaviour { /// <summary>索引</summary> public int iInx = 0; /// <summary>宣告滑鼠移入按鈕事件,輸出類型為int</summary> public EventSenderT<int> evtBtnEnter = new EventSenderT<int>(); /// <summary>宣告滑鼠移出按鈕事件,沒有輸出值</summary> public EventSender evtBtnExit = new EventSender(); /// <summary>當滑鼠移入時</summary> void OnMouseEnter () { //發佈事件,輸出類型為int,int的值為iInx evtBtnEnter.DoSomething(iInx); } /// <summary>當滑鼠移出時</summary> void OnMouseExit () { //發佈事件,沒有輸出值 evtBtnExit.DoSomething(); } }
而其他程式只需要在事件發佈之前,預先訂閱事件,
假設我們在<PanLogin>訂閱了<ButtonArthur>的 evtBtnEnter 及 evtBtnExit 事件,
並且把<PanLogin>掛在場景中隨便一個物件上:
using UnityEngine; using System.Collections; public class PanLogin : MonoBehaviour { /// <summary>打算訂閱的按鈕,要記得將指標指向場景中的<ButtonArthur></summary> public ButtonArthur btn = null; void Awake () { //先訂閱事件,當收到事件時,事件內容會輸入此處指定的函式 btn.evtBtnEnter.Register(onBtnEnter); //先訂閱事件,當收到事件時,事件內容會輸入此處指定的函式 btn.evtBtnExit.Register(onBtnExit); } //對應事件當初宣告的類型,輸入值必須為int void onBtnEnter (int i_i) { //顯示收到的事件內容 Debug.Log (i_i); //若要解除訂閱,只要使用UnRegister函式即可 btn.evtBtnEnter.UnRegister(onBtnEnter); } //對應事件當初宣告的類型,不能有輸入值 void onBtnExit () { //顯示收到事件 Debug.Log ("onBtnExit"); //若要解除訂閱,只要使用UnRegister函式即可 btn.evtBtnExit.UnRegister(onBtnExit); } }
順道一提,當多個程式都訂閱了同一事件時,
是依照訂閱順序來處理的,一個處理完才換下一個。
訂閱時也要注意,若多次訂閱同一事件的話,就像同一份報紙訂了N次,
到時當然會收到N份報紙了。
因此若不需要接收事件時,就可以使用UnRegister來解除訂閱,
即使原本沒有訂閱該事件,對其解除訂閱時也不會出錯,可以安心使用。
沒有留言:
張貼留言