unity3d 使用委託+事件 完成低耦合傳送訊息
最近在自學unity3d,看了網上的一些教學視訊和小遊戲按鈕,感覺gameobject與gameobject 的訊息傳遞,程式碼耦合性很強,因為我是開發as3的用的是面向物件的MVC思想,所以看到耦合性強的程式碼就有點強迫症去修改它,以下是用委託+事件做的一個低耦合的訊息傳遞;不說廢話,進入主題;
首先建立一個簡單的場景,一個plane,放在上面的兩個cube,其中一個cube(稱為A)移動撞向另一個cube(稱為B),撞了之後A向B傳送 一個訊息,能自定義訊息的;
一個單例去儲存委託和事件,(懂as3的朋友,這個單例相當一個事件的dispacter),程式碼如下
using UnityEngine;
using System.Collections;
/// <summary>
/// 單例
/// </summary>
public class EventDispacter{
//例項化單例
private static EventDispacter instance;
//定義委託事件,它定義了可以代表的方法的型別
/**碰撞檢測*/
public delegate void CollisionHandler(DataType evt);
public event CollisionHandler CollisionHapend;
private EventDispacter(SingletonEnforcer enforcer){
}
public static EventDispacter getInstance()
{
if(instance==null)
{
instance=new EventDispacter(new SingletonEnforcer());
}
return instance;
}
public void sendCollisionHapend(DataType evt){
if(CollisionHapend!=null)CollisionHapend (evt);
}
}
class SingletonEnforcer {}
自定義訊息的方法如下:
using UnityEngine;
using System.Collections;
public class DataType{
//定義委託事件傳送訊息的內容,或者其他東西
private string txt;
public string Txt{
get{return txt;}
set{txt=value; }
}
}
在A cube這個物體的指令碼中
using UnityEngine;
using System.Collections;
public class Cmain : MonoBehaviour {
//要傳遞的內容
private DataType d;
void OnTriggerEnter (Collider c){
//print ("Cmaincrash");
//if (EventDispacter.getInstance().CollisionHapend) {
d = new DataType ();
d.Txt = "Success to send a message!!";
//傳送事件
EventDispacter.getInstance().sendCollisionHapend(d);
//}
}
// Update is called once per frame
void Update () {
transform.Translate (new Vector3 (1, 0, 0)*Time.deltaTime);
}
}
在B cube中指令碼如下:
using UnityEngine;
using System.Collections;
public class CSon : MonoBehaviour {
// Use this for initialization
void Start () {
//監聽傳送的事件
EventDispacter.getInstance().CollisionHapend+=dealFun;
}
// Update is called once per frame
void dealFun(DataType d) {
print (d.Txt);
}
void OnDestroy(){
//移除傳送的事件
//這個移除很重要,因為unity銷燬的是隻是自身的物體,對於這種事件的引用不會回收,如果銷燬了該物體卻不移除該事件監聽的話則會提示
//該物體已經銷燬卻嘗試去連線它,而且該事件監聽一直會佔著記憶體
EventDispacter.getInstance().CollisionHapend-=dealFun;
}
}
這樣就完成了一個gameobject向另外一個或者多個gameobject傳送訊息,又不會產生強耦合的問題;
發這博文一是希望學unity3d的朋友覺得我哪裡寫得不好的話指出來,一起探討,二是激勵自己,自學需要動力啊