程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 【Unity3D技巧】在Unity中使用事件/委托機制(event/delegate)進行GameObject之間的通信

【Unity3D技巧】在Unity中使用事件/委托機制(event/delegate)進行GameObject之間的通信

編輯:C#入門知識

作者:王選易,出處: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);
另一種更好的委托方式是使用泛型參數的委托類型:EventHandler<TEventArgs>,其簽名如下:
public delegate void EventHandler<TEventArgs>(
    Object sender,
    TEventArgs e
)

采用 EventHandler 模式發布事件

如果這個事件不產生任何額外參數(即除了事件的發送者之外),則在在調用時,向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);
    }

}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved