他為了讓更多人能使用這個簡潔方便的事件處理器,就由我在此跟大家分享囉!
使用方式很簡單,只要將這兩個元件檔案<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來解除訂閱,
即使原本沒有訂閱該事件,對其解除訂閱時也不會出錯,可以安心使用。