作者:王選易,出處:http://www.cnblogs.com/neverdie/ 歡迎轉載,也請保留這段聲明。如果你喜歡這篇文章,請點【推薦】。謝謝!
// 該委托不傳任何參數
public delegate void CallFunc();
// 該委托會傳入發生事件的GameObject,即sender
public delegate void CallFuncO(GameObject sender);
// 該委托會傳入發生事件的GameObject,即sender。和一個變長參數列表
public delegate void CallFuncOP(GameObject sender, EventArgs args);
但是我發現C#本身已經提供了一種比較好的委托類型:EventHandler,所以我就把游戲中的委托都替換成了這種委托。
public delegate void EventHandler(object sender, EventArgs e);
public delegate void EventHandler<TEventArgs>(
Object sender,
TEventArgs e
)
如果這個事件不產生任何額外參數(即除了事件的發送者之外),則在在調用時,向EventHandler的第二個參數傳一個EventArgs.Empty即可。
如果產生額外參數,第二個參數是從 EventArgs 派生的類型並提供所有字段或屬性需要保存事件數據。使用 EventHandler<TEventArgs> 的優點在於,如果事件生成事件數據,則無需編寫自己的自定義委托代碼。
下面我們舉一個例子來證實EventHandler的用法:
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Counter c = new Counter(new Random().Next(10));
//向該事件添加了一個委托函數
c.ThresholdReached += c_ThresholdReached;
Console.WriteLine("press 'a' key to increase total");
while (Console.ReadKey(true).KeyChar == 'a')
{
Console.WriteLine("adding one");
c.Add(1);
}
}
static void c_ThresholdReached(object sender, ThresholdReachedEventArgs e)
{
Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached);
Environment.Exit(0);
}
}
class Counter
{
private int threshold;
private int total;
public Counter(int passedThreshold)
{
threshold = passedThreshold;
}
public void Add(int x)
{
total += x;
if (total >= threshold)
{
ThresholdReachedEventArgs args = new ThresholdReachedEventArgs();
args.Threshold = threshold;
args.TimeReached = DateTime.Now;
OnThresholdReached(args);
}
}
protected virtual void OnThresholdReached(ThresholdReachedEventArgs e)
{
EventHandler<ThresholdReachedEventArgs> handler = ThresholdReached;
if (handler != null)
{
handler(this, e);
}
}
//添加了一個帶泛型參數的事件
public event EventHandler<ThresholdReachedEventArgs> ThresholdReached;
}
public class ThresholdReachedEventArgs : EventArgs
{
public int Threshold { get; set; }
public DateTime TimeReached { get; set; }
}
}
我們通過一個小鳥撞倒管子來作為事例說明如何進行通信:
using UnityEngine;
using System.Collections;
using System;
public class BirdController : MonoBehaviour {
public event EventHandler GameOver;
public event EventHandler ScoreAdd;
//當離開Empty Trigger的時候,分發ScoreAdd事件
void OnTriggerExit2D(Collider2D col) {
if (col.gameObject.name.Equals("empty")) {
if (ScoreAdd != null)
ScoreAdd(this, EventArgs.Empty);
}
}
//當開始碰撞的時候,分發GameOver事件
void OnCollisionEnter2D(Collision2D col)
{
rigidbody2D.velocity = new Vector2(0, 0);
if (GameOver != null)
GameOver(this, EventArgs.Empty);
this.enabled = false;
}
}
然後在對這個事件感興趣的GameObject會通過相應的Handler對該事件進行監聽,這樣就可以進行一對多的GameObject間的通信了。
using UnityEngine;
using System.Collections;
using System;
public class TubeController : MonoBehaviour {
// Use this for initialization
void Start () {
GameObject.Find("bird").GetComponent<BirdController>().GameOver += OnGameOver;
}
void OnDestroy() {
if ( GameObject.Find("bird") )
GameObject.Find("bird").GetComponent<BirdController>().GameOver -= OnGameOver;
}
void OnGameOver(object sender, EventArgs e)
{
rigidbody2D.velocity = new Vector2(0, 0);
}
}