在本文,你將學到如何在Unity3D中使用系統自帶委托
EventHandler
完成事件的聲明訂閱和執行;
寫在前面:
EventHandler是什么?
System.EventHandler
是IDE提供的封裝好含有2個參數(object sender
,EventArgs e
)的委托,前面參數是事件發送者object sender
,后面是事件詳情標簽(傳遞事件的細節)EventArgs e
;
有了這樣的體貼入微的委托,我們就不用重新聲明類似的委托啦!
如何用在Unity3d呢?
要想在Unity3D里面使用呢,肯定就是被訂閱的方法簽名必須與委托定義的簽名保持一致呀。
方法必須形如:
void MethodName(object sender,EventArgs e){yourCode}
;
但是這樣問題就來啦:
- 我怎么能把我們的游戲對象作為參數傳過去呢?
- 我怎么拿出EventArgs的信息呢?
首先講講第一個參數:
在Unity3D里面,所有物體均可稱為一個游戲對象GameObject
,而它的基類就是object
,完美,也就是說Unity3D里面的游戲對象都可以作為事件發送方出現在這個委托的第一個參數里面呢~
其次我們說說第二個參數:
EventArgs是事件詳情類的基類,在Unity3D里面直接使用得不到啥有用的信息,咋整?
其實,需要我們繼承這個基類,寫自己的事件詳情頁:MyEventArgs
,想要訂閱的方法得到啥你就把啥整進去就好咯!
然后,事件執行的時候new
一個MyEventArgs
的對象,傳進去就好啦!
原理我們懂了,現在具體實現下:
首先,寫一個類EventSender
,利用EventHandler
聲明事件OnMoveCompleteHandle
,并公開執行方法DoItNow()
讓外部可以主動執行那些訂閱了事件的方法(在EventSender
類中也可以定義如何執行這個事件,但是寶寶不寫)
using UnityEngine;
using System;
public class EventSender : MonoBehaviour
{
public event EventHandler OnMoveCompleteHandler;
/// <summary>
/// 事件觸發執行的方法,Public方便外界調用,誰執行,誰給執行細節
/// </summary>
/// <param name="go">誰執行,誰就傳遞GameObject</param>
/// <param name="e">誰執行,誰就傳遞事件細節信息,如果自定義的,就New一個,如果是系統默認的就用EventARgs.Empty確保簽名一致性</param>
public void DoItNow(GameObject go, MyEventArgs e) //這個在執行時由外部觸發方傳參數,誰執行誰定義參數,很靈活方便
{
if (OnMoveCompleteHandler != null)
{
OnMoveCompleteHandler(go, e);
}
}
public void DoItNow()//這個不管是誰外部觸發的,參數均為EventSender預先定義OK的,顯然很多不便
{
if (OnMoveCompleteHandler != null)
{
OnMoveCompleteHandler(gameObject, new MyEventArgs(520, "事件詳情生成方為事件聲明方,也就是“EventSender”"));
}
}
}
自定義信息細節類:
在這個類,你可以把事件發布方,執行方亦或是訂閱方的家底都打包拋出去
using System;
/// <summary>
/// 繼承EventArgs自定義自己的事件細節信息,這里只演示傳遞2種變量信息,實際使用可傳遞的信息那就多了,你想傳啥都可以;/// </summary>
public class MyEventArgs : EventArgs
{
private string message;
private int id;
public string Message{ get { return message; } private set { message = value; } }
public int Id{get{return id;}private set { id = value; } }
public MyEventArgs(int _id,string _message)
{
Id= _id;
Message = _message;
}
}
寫一個訂閱事件的類:
using System;
using UnityEngine;
public class EventReceive : MonoBehaviour {
public EventSender tc;
void Start()
{
tc.OnMoveCompleteHandler += TestFunc; //事件的訂閱
}
private void TestFunc(object sender, EventArgs e)//具體執行的方法,函數簽名必須與委托定義的保持一致
{
GameObject go = (GameObject)sender; //我們知道我們傳遞了什么過來;
MyEventArgs ag = (MyEventArgs)e; //所以強轉獲得事件執行方給的各種信息;
Debug.Log("游戲對象是:" + go.name + ";消息是:“" + ag.Message + "”,消息ID為:" + ag.Id);
}
void Update()
{
if (Input.GetMouseButtonDown(0)) //按左鍵執行事件,這個事件里面傳遞的值是預先定義的哈,改不了
{
Debug.Log("我按下了左鍵");
tc.DoItNow();
}
else if (Input.GetMouseButtonDown(1))//按右鍵執行另一個重載,這下我們能自由發揮給我們的訂閱者發送我想給的參數啦,是不是感覺好暢快呀!
{
Debug.Log("我按下了右鍵");
tc.DoItNow(gameObject, new MyEventArgs(520520, "事件詳情生成方為事件訂閱方,也就是“EventReceive”"));
}
}
}
動畫演示一下:
如何結合UI控件使用呢?
結合筆者前面寫的UGUI Button OnClick事件統一管理,將Update
里面測試用的那句寫到AddListener
里面就可以實現啦~
直接上手測試UnityPackage
標簽:Unity3D、事件系統、EventHandler,EventArgs、在Unity中使用EventHandler