1. 程式人生 > >C#內置的事件機制和Unity3D姻緣

C#內置的事件機制和Unity3D姻緣

mono 需要 listen 存在 logs sharp strong 關聯 有一種

最近因為項目,也因為一些其他事情而導致學習的停止,抽個空來記錄下C#內置的事件在Unity3D中的使用。

我需要讓一個物體對鼠標懸停做出事件的響應的情況下,我們通常會創建一個繼承MonoBehaviour的腳本然後掛到該物體上,然後為該腳本創建OnMouseOver方法,例如我們需要懸停來改變物體顏色,可能會這樣寫。

using UnityEngine;
using System.Collections;

public class ChangeColor : MonoBehaviour {

    void OnMouseOver()
    {
        transform.GetComponent
<Renderer>().material.color = Color.red; } }

這樣就實現了我們需要的目的,但是,問題又來了,我們需要讓另外的對象響應該事件呢?

解決辦法是保持另外對象的腳本引用,然後在你的OnMouseOver方法中調用它。這樣做沒問題,但是不夠好。因為你需要一直保持另外一個對象的引用,如果想通知多個對象要保持多個引用。代碼會變得很亂。

還有一種方法是Messages 消息

使用SendMessage或SendMessageUpwards方法。看上去這是解決問題的最好辦法,但是這些方法存在嚴重的缺陷,以我的觀點,你應該盡量不去使用它們。

這些方法的語法並不靈活,你需要傳遞一個方法名字的字符串,這樣做很容易出錯。另外這些方法只能用在同一個對象的附屬關系中。換句話說你只能在下面幾種情況中調用SendMessage或SendMessageUpwards方法,這些方法的腳本被關聯到同一個GameObject中,或者被關聯到這個GameObject的祖先關系對象中。

幸運的是有一個更好的解決辦法,這就是C#內置的事件機制

我們先來看一下如何在Unity3D中使用事件機制。

public class ChangeColor : MonoBehaviour {
public delegate void EventHandler(GameObject e);
public event EventHandler MouseOver;
void OnMouseOver()
{
if (MouseOver != null)
MouseOver(this.gameObject);
}

}

我們把該腳本掛的物體A,然後新建一個腳本。

public class ChangeColor1 : MonoBehaviour {

    private GameObject _gameObject;

    // Use this for initialization
    void Start () {
        [...]
        _gameObject.GetComponent<ChangeColor>().MouseOver += Listener;
        [...]
    }

    void Listener(GameObject g)
    {

Debug.Log("響應事件的物體是 " + this.gameObject.name);
Debug.Log("觸發事件的物體是 "+g.name);

    }

}

這種方式比用消息更靈活,因為它可以被用在任何一個腳本中,而不僅僅在同一個對象附屬關系中。如果在整個應用中保持一個單例模式的對象,你就可以監聽任何從這個對象分發出來的事件。另外一個重要特點,同一個監聽方法可以響應不同對象的事件。通過傳遞事件源對象的引用作為參數,你總會知道哪個對象分發了事件。

C#內置的事件機制和Unity3D姻緣