免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
C# 事件和Unity3D
     翻譯自:
http://www.everyday3d.com/blog/index.php/2010/10/04/c-events-and-unity3d/

zijan譯

(括號內是譯者自己對文章和技術的理解)
(Unity3D是現在越來越流行的3D游戲引擎,它支持JavaScript,c#和Boo語言。如果你是個Unity3D的愛好者,但只會JavaScript。這里有一篇文章關于處理事件和消息傳遞,也許更適合你。A Useful Messaging System

你知道C#有一個內置的事件機制嗎?這個東東在Unity3D里也非常好用。下面舉一個例子。

為了響應一個GameObject的事件分發(fā),你通常要建立一個腳本繼承MonoBehaviour并且實現你需要的方法。比如你想對鼠標懸停作出反應,就要創(chuàng)建OnMouseOver方法。通常代碼會像這個樣子:

C#代碼  
  1. void OnMouseOver () {  
  2.   renderer.material.color = Color.red;  
  3. }  



這樣工作沒問題。但如果你想通知另外一個對象響應這個事件(OnMouseOver事件)怎么辦?

第一種方式是保持另外對象的腳本引用,然后在你的OnMouseOver方法中調用它:

C#代碼  
  1. public MyScript myScript;  
  2. void OnMouseOver () {  
  3.   myScript.NotifyMouseOver();  
  4. }  



這樣做沒問題,但是不夠好。因為你需要一直保持另外一個對象的引用,如果想通知多個對象要保持多個引用。代碼會變得很亂。

Messages 消息

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

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

Events 事件

幸運的是有一個更好的解決辦法,這就是C#內置的事件機制。我不在這里過多的描述機制是如何工作的,你如果有興趣可以學習相關的知識,訪問MSDN手冊。(譯者推薦另外一篇文章,C# 中的委托和事件

現在讓我們看看如何在Unity3D中使用事件機制。

C#代碼  
  1. using UnityEngine;  
  2. public class EventDispatcher : MonoBehaviour {  
  3.   public delegate void EventHandler(GameObject e);  
  4.   public event EventHandler MouseOver;  
  5.   void OnMouseOver () {  
  6.     if (MouseOver != null)  
  7.         MouseOver (this.gameObject);  
  8.   }  
  9. }  


如果你不知道這段代碼到底干什么,先不要著急。重要的是一旦你把這段代碼關聯(lián)到一個GameObject,只要在整個項目的任何一個腳本中保持這個對象,你就可以像下面這樣處理事件:

C#代碼  
  1. private GameObject s;  
  2. [...]  
  3. s.GetComponent<EventDispatcher>().MouseOver += Listener;  
  4. [...]  
  5. void Listener(GameObject g) {  
  6.    // g is being hovered, do something...  
  7. }  


這種方式比用消息更靈活,因為它可以被用在任何一個腳本中,而不僅僅在同一個對象附屬關系中。如果在整個應用中保持一個單例模式的對象,你就可以監(jiān)聽任何從這個對象分發(fā)出來的事件。

另外一個重要特點,同一個監(jiān)聽方法可以響應不同對象的事件。通過傳遞事件源對象的引用作為參數,你總會知道哪個對象分發(fā)了事件,就像我的代碼展示的那樣。(對于這句話可以這樣理解,假如游戲中扔一顆導彈炸死了一個小兵并導致坦克減血,小兵死亡和坦克減血這兩個事件都觸發(fā)了同一個監(jiān)聽方法-玩家得分,通過傳遞進來的事件源對象,就能知道小兵還是坦克觸發(fā)了玩家得分這個監(jiān)聽方法。)

References, controllers and MVC

現在讓我們比較一下第一和第三種方式。在最開始的例子中(第一種方式保持另外對象的腳本引用),你需要在事件分發(fā)代碼中保持監(jiān)聽者的對象引用,我說了這不是一個好主意。在用內置事件機制,改進的版本中(第三種方式),你需要在監(jiān)聽者代碼中保持事件分發(fā)者的引用。你也許會問,為什么后者更好?

首先,分發(fā)者不需要知道自己事件的監(jiān)聽者是誰,不需要知道有多少監(jiān)聽者。它只負責事件的發(fā)送。在最開始的例子中(第一種方式),如果要告訴分發(fā)者停止通知監(jiān)聽者,你能想象這種程序判斷有多么笨重嗎?

事件機制中,是由監(jiān)聽者自己決定監(jiān)聽什么事件,什么時候開始監(jiān)聽,什么時候停止監(jiān)聽。像這樣的對象通常用于管理程序的狀態(tài)或者執(zhí)行某些游戲邏輯。這個就叫做控制器,借用MVC設計模式的概念。這樣我們的代碼會更清晰,不易出錯。(譯者認為觀察者設計模式更符合)

最后一點,我喜歡重載“+=”操作符去添加監(jiān)聽方法。現在你也許能夠猜到,如果想結束監(jiān)聽某個事件,可以這么寫:

C#代碼  
  1. s.GetComponent<EventDispatcher>().MouseOver -= Listener;  


當然你可以創(chuàng)建一個通用的EventDispatcher類,實現所有GameObject能夠分發(fā)的事件??梢詤⒖聪旅娴拇a。另外在實現OnGUI事件時要特別小心,如果想知道為什么,讀讀這篇文章。

C#代碼  
  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. /**  
  5.  *  A simple event dispatcher - allows to listen to events in one GameObject from another GameObject 
  6.  * 
  7.  *  Author: Bartek Drozdz (bartek [at] everyday3d [dot] com) 
  8.  * 
  9.  *  Usage: 
  10.  *  Add this script to the object that is supposed to dispatch events.  
  11.  *  In another objects follow this pattern to register as listener at intercept events: 
  12.   
  13.     void Start () { 
  14.         EventDispatcher ev = GameObject.Find("someObject").GetComponent<EventDispatcher>(); 
  15.         ev.MouseDown += ListeningFunction; // Register the listener (and experience the beauty of overloaded operators!) 
  16.     } 
  17.  
  18.     void ListeningFunction (GameObject e) { 
  19.         e.transform.Rotate(20, 0, 0); // 'e' is the game object that dispatched the event 
  20.         e.GetComponent<EventDispatcher>().MouseDown -= ListeningFunction; // Remove the listener 
  21.     } 
  22.      
  23.  *  This class does not implement all standards events, nor does it allow dispatching custom events,  
  24.  *  but you shold have no problem adding all the other methods. 
  25.  */  
  26. public class EventDispatcher : MonoBehaviour  
  27. {  
  28.   
  29.     public delegate void EventHandler (GameObject e);  
  30.     public delegate void CollisionHandler (GameObject e, Collision c);  
  31.   
  32.     public event EventHandler MouseOver;  
  33.     void OnMouseOver ()  
  34.     {  
  35.         if (MouseOver != null)  
  36.             MouseOver (this.gameObject);  
  37.     }  
  38.   
  39.     public event EventHandler MouseDown;  
  40.     void OnMouseDown ()  
  41.     {  
  42.         if (MouseDown != null)  
  43.             MouseDown (this.gameObject);  
  44.     }  
  45.   
  46.     public event EventHandler MouseEnter;  
  47.     void OnMouseEnter ()  
  48.     {  
  49.         if (MouseEnter != null)  
  50.             MouseEnter (this.gameObject);  
  51.     }  
  52.   
  53.   
  54.     public event EventHandler MouseExit;  
  55.     void OnMouseExit ()  
  56.     {  
  57.         if (MouseExit != null)  
  58.             MouseExit (this.gameObject);  
  59.     }  
  60.   
  61.     public event EventHandler BecameVisible;  
  62.     void OnBecameVisible ()  
  63.     {  
  64.         if (BecameVisible != null)  
  65.             BecameVisible (this.gameObject);  
  66.     }  
  67.   
  68.     public event EventHandler BecameInvisible;  
  69.     void OnBecameInvisible ()  
  70.     {  
  71.         if (BecameInvisible != null)  
  72.             BecameInvisible (this.gameObject);  
  73.     }  
  74.   
  75.     public event CollisionHandler CollisionEnter;  
  76.     void OnCollisionEnter (Collision c)  
  77.     {  
  78.         if (CollisionEnter != null)  
  79.             CollisionEnter (this.gameObject, c);  
  80.     }  
  81.   
  82.     public event CollisionHandler CollisionExit;  
  83.     void OnCollisionExit (Collision c)  
  84.     {  
  85.         if (CollisionExit != null)  
  86.             CollisionExit (this.gameObject, c);  
  87.     }  
  88.       
  89. }  
本站僅提供存儲服務,所有內容均由用戶發(fā)布,如發(fā)現有害或侵權內容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
unity3d學習筆記(十八)利用C#的代理和事件結合NGUI的按鈕實現施放
UGUI基礎
Unity3D之將UI的點擊事件滲透下去(九十)
【Unity技巧】自定義消息框(彈出框)
淺析C#的事件處理和自定義事件
Unity
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服