Unity[C#] Reflection Use

來源:互聯網
上載者:User

標籤:style   blog   http   color   使用   檔案   

Reflection一個最有力的工具對於C#程式員。

最常用的例子來說明反射的用處是一個外掛程式系統。假設你正在建立一個 接受使用者建立 的擴充程式,有沒有辦法預Crowdsourced Security Testing道哪些方法這個擴充他們有或有擴充的名字將是什麼,除非你可以檢查編譯的程式集,並在運行時提取資訊,這正是反射呢,等等

目前,我正在開發一個遊戲在Unity(一個多平台的遊戲引擎和IDE),在使用者 介面是“在遊戲中”。這意味著,而是採用Unity提供的API,它提供了相當強大的工具集來建立互動式圖形化使用者介面的,我把3D對象在遊戲中的情境,必須響應使用者的輸入。Unity讓你檢測滑鼠事件,但沒有辦法編寫單個事件處理常式以模組化的方法。

為了得到這個功能,我不得不擴充Unity的Editor和Inspecot 來暴露My Code,這聽起來很複雜,但這些定位方法,並隨後調用它們的底層代碼很簡單。

第1步:暴露你需要的方法

之前,我們接觸過C#的Reflection API,我們需要建立一個新的屬性,

Attributes allow us to assign metadata to classes, methods, properties, etc. that can be read back by reflection.

屬性允許我們指定方法,類屬性等等,可以通過反射來讀到這些值。

In this case, our attribute is going to be called “ExposeToEditor” and we‘re going to use it to tag instance methods (and classes with static methods) that Unity‘s editor should recognise as valid event handlers.

在這種情況下,我們的屬性將被稱為:ExposeEditor ,我們打算用它來標記Instance(和類的靜態方法)Unity的Editor可以識別出它們是有效事件處理常式

因此,我們建立了一個新的指令檔,並確保 using Systm;在頂部,然後我們編寫以下代碼:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
     public class ExposeToEditor : Attribute { }

這將建立一個標準屬性系統,我們現在可以分配給任何方法或類,例如:

[ExposeToEditor]
      public void OnThisButtonClick(object sender) { };

現在,我們可以放在一起,將跟蹤標識以這種方式方法的代碼 第2步:接下來的工作定位我們的Public的方法

點擊上面的映像,將其展開,並期待在最右邊的面板中-你會看到一個名為:Interface Click Handler的指令碼。這是一個Editor的介面,我們編碼,可以讓我選擇包含我所需要的指令碼和方法的特定對象。此圖片是更提供上下文是什麼,我來解釋,而不是使用Reflection的重要組成部分。因此,如果它沒有多大,不用擔心。

最重要的是這些背後的編輯器介面,它需要定位的方法在指令碼的邏輯,下面是關鍵的部分

var type = t.OnClickMonoBehaviour.GetType(); List<string> methodNames = new List<string>();List<MethodInfo> methods = new List<MethodInfo>(type.GetMethods()); foreach (MethodInfo mi in methods){    if (mi.IsDefined(typeof(ExposeToEditor), true))    {        methods.Add(mi);        methodNames.Add(mi.Name);    }}

讓我們把它分解,我們要做的第一件事情就是,擷取選定的指令碼類型,後者被儲存 在 OnClickMonoBehaviour 對象的屬性t。然後我們執行個體化一些List來儲存這些方法的資訊,foreach 迴圈遍曆擷取所有的包含在這個Script Type的public方法,通過type.GetMethods;

.GetMethods為我們提供一個數組的MethodInfo對象,.MethodInfo包含了大量的關於每個方法的資訊,我們可以使用甚至該方法MethofInfo.Invoke.然而,這並不是最有效方式來動態調用一個方法,以後的東西我會介紹。

現在,我們不希望來儲存所有的方法,我們只是想通過那些我們先前建立的屬性暴露出來,因此,我們使用MethofInfo.IsDefind() 方法來檢查是否 ExposeToEditor 串連到該方法。要徹底,我們告訴 IsDefind 檢查繼承的類型也是如此。

一旦迴圈完成之後,我們將不得不包含的方法作為字串不只是名字,但是這些方法本身,在形式列表 MethofInfo 對象。的字串列表是用來填充的最後一個影像的”關於Click 方法” 下拉式清單中,這樣我們就可以很容易地選擇正是我們所需要的。

第3步:儲存和動態調用方法

用方法名儲存,所有我們現在需要做的是理清了“Click” 的邏輯,這是用來在遊戲中,正如我們前面提到的,要做到這一點最簡單的方式是通過使用MethodInfo的動態調用。例如:

MethodInfo mi = VariableContainingMethodInfo;
     mi.Invoke();

並沒有什麼真的錯了,這幹得不錯,但是,我們可以執行通過使用  Action<T> Delegate 並緩衝它

首先,我們在某處定義緩衝變數

private Action<object> CacheAction;

然後,當介面元件由玩家互動,我們緩衝的方法,並用它在隨後的相互作用。

CachedAction = (Action<object>)Delegate.CreateDelegate(typeof(Action<object>),OnClickMonoBehaviour,OnClickMethod);

現在,有幾個重載 Delegate.CretaeDelegate ,在這種情況下 OnClickMonoBehaviour 和 OnClickMethod 都是字串。委託建立並儲存在CacheAction ,所以當我們要調用它,我們只是這樣做:

CacheAction(object);

在這兒 object 只是一個靈活的參數,我們可以根據需要將資訊傳遞到事件處理常式。

The best way to get more familiar with it is to check it out on MSDN. For more practical examples, Stack Exchange is a valuable resource, providing specific examples of how to get reflection doing what you want it to.

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.