Unity中的訊息機制
阿新 • • 發佈:2019-02-05
在遊戲開發中,我們經常需要傳遞訊息。
傳遞訊息一般有三種方法:
1. 儲存物件的引用。
2. Unity 提供的 Message機制。
3. C#中的委託和事件。
儲存物件的引用
例如手榴彈爆炸的時候, 需要獲取手榴彈, 地面, 附近物體等遊戲元素的物件, 然後播放爆炸特效。
這種方法是簡單粗暴, 但是當專案的規模變大時, 增刪改查將會變的很麻煩。
其實這是一種耦合度較高的方案。
Unity 提供的 Message機制
Unity 本身提供了一種Messages訊息機制。
-
- Calls the method named methodName on every MonoBehaviour in this game object or any of its children.
- 對一個物體及其所有子物體,進行訊息的廣播,如果其中任何子物體上貼有指令碼,而指令碼中有相應的處理此訊息的函式,則Invoke呼叫。
- BroadcastMessage 朝物體和所有子物體傳送訊息。
-
- Calls the method named methodName on every MonoBehaviour in this game object.
- 在遊戲物體每一個 MonoBehaviour 上呼叫名為methodName的方法。
- SendMessage 朝本級別物體的多個指令碼傳送資訊,也就是向當前物件掛載的所有指令碼上面傳送訊息。 (父物體、子物體中所有MonoBehavior都不會接收到該訊息,即使包含methodName的方法)
-
- Calls the method named methodName on every MonoBehaviour in this game object and on every ancestor of the behaviour.
- 在遊戲物體每一個 MonoBehaviour 和每一個 behaviour 的祖先上呼叫名為methodName的方法。
- SendMessageUpwards朝物體和上級父物體傳送資訊。
C#中的事件
C#中的委託和事件,對於訊息傳遞來說非常好用,從設計模式的角度上來說,是一個典型的觀察者模式。
例如我們實現一個搖桿, 可以在設計 RockerTouchBegin, RockerTouchMove, RockerTouchEnd 三個事件,
而對這個事件感興趣的物件會通過相應的 Handler 對該事件進行監聽,這樣就可以進行一對多的 GameObject 間的通訊了。
具體可以參考下面給出的實現。
public class Rocker : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler {
public delegate void RockerTouchBegin(Vector2 vec);
public delegate void RockerTouchMove(Vector2 vec);
public delegate void RockerTouchEnd();
public event RockerTouchBegin OnTouchBegin;
public event RockerTouchMove OnTouchMove;
public event RockerTouchEnd OnTouchEnd;
private bool isTouched = false;
public void OnPointerDown(PointerEventData eventData) {
isTouched = true;
if (null != OnTouchBegin)
OnTouchBegin(eventData.position);
}
public void OnPointerUp(PointerEventData eventData) {
isTouched = false;
if (null != OnTouchEnd)
OnTouchEnd();
}
public void OnDrag(PointerEventData eventData) {
if (null != OnTouchMove)
OnTouchMove(eventData.position);
}
}
private Rocker rocker;
void Start() {
rocker = FindObjectOfType<Rocker>();
rocker.OnTouchBegin += OnTouchBegin;
rocker.OnTouchMove += OnTouchMove;
rocker.OnTouchEnd += OnTouchEnd;
}
void OnTouchBegin(Vector2 vec) {
Debug.Log("OnTouchBegin");
}
void OnTouchMove(Vector2 vec) {
Debug.Log("OnTouchMove");
}
void OnTouchEnd() {
Debug.Log("OnTouchEnd");
}
如有錯誤,歡迎指出。
email:dxmdxm1992#gmail.com