Unity3D編輯器插件

在閱讀本教程之前,你需要對Unity的操作流程有一些基礎的認識,並且最好了解內置的GUI系統如何使用。
如何讓編輯器運行你的代碼如何讓編輯器運行你的代碼
Unity3D可以通過事件觸發來執行你的編輯器代碼,但是我們需要一些編譯器參數來告知編譯器何時需要觸發該段代碼。 [MenuItem(XXX)]聲明在一個函數上方,告知編譯器給Unity3D編輯器添加一個菜單項,並且當點擊該菜單項的時候調用該函數。觸發函數裏可以編寫任何合法的代碼,可以是一個資源批處理程序,也可以彈出一個編輯器窗口。代碼裏可以訪問到當前選中的內容(通過Selection類),並據此來確定顯示視圖。與此類似,[ContextMenu("XXX")]可以向你的上下文菜單中添加一個菜單項。 當你編寫了一些Component腳本,當它被附屬到某個GameObject時,想在編輯視圖即可在Scene視圖觀察到效果,那麼你可以把[ExecuteInEditMode]寫在類上方來通知編譯器,該類的OnGUI和Update等函數在編輯模式也也會被調用。我們還可以使用[AddComponentMenu("XXX/XXX")]來把該腳本關聯到Component菜單中,點擊相應菜單項即可爲GameObject添加該Component腳本。
開始編寫編輯器
爲了避免不必要的包含,Unity3D的運行時和編輯器類分辨存儲在不同的Assemblies裏(UnityEngine和UnityEditor)。當你準備開始編寫編輯器之前,你需要using UnityEditor來導入編輯器的名稱空間。 有些代碼可能是運行時和編輯器都需要執行的,如果你想在其中加以區分,那麼可以使用#if UNITY_EDITOR ... #endif宏來對編輯器代碼做特殊處理。 在你開始真正編寫代碼之前,我認爲你還需要知道所有放在命名爲Editor目錄下的腳本會在其它腳本之後進行編譯,這方便了你去使用那些運行時的內容。而那些目錄下的腳本是不能訪問到Editor目錄下的內容的。所以,你最好把你的編輯器腳本寫在Editor目錄下。
如何創建自定義編輯器窗口
創建你的窗口
如果你想自定義一個可編輯的面板,那麼你需要編寫一個繼承自EditorWIndow的類。通常情況下,你還需要寫一個[MenuItem]來告知編譯器何時打開這個面板。這個事件的回調應該是一個靜態方法,並且返回一個窗口的實例。

現在,當你點擊對應的菜單項時,會彈出一個空白的窗口。並且你可以像Unity3D編輯器預製的窗口一樣隨意拖動和停靠。下面來看看我們如何來在窗口內實現我們想要的功能吧。
擴展你的窗口
和運行時的GUI一樣,如果你需要在窗口中添加交互控件,那麼必須重寫OnGUI方法。具體的重寫方式和運行時的GUI一樣,你甚至可以使用任何擴展自原生GUI系統的插件(例如iGUI和GUIX)來簡化你的插件開發流程(僅經過初步測試,更深層次的可用性尚待驗證)。同時UnityEditor名稱空間下的EditorGUILayout在原生GUI之上提供了一些更方便的接口和控件,讓你可以輕鬆的使用一些編輯器特有的UI控件。 除了OnGUI外,你可能還會需要如下一些回調來觸發某些具體的邏輯(完整的列表請參考官方文檔):  OnSelectionChange,但你點選物品時觸發  OnFocus /OnLostFocus,獲得和失去焦點時觸發
進一步擴展你的窗口
自定義控件  和運行時GUI的使用方式一樣,如果你打算自定義自己的控件,那麼最簡單的方式就是實現一個靜態方法(也可以不是靜態的),並提供一些可選參數,在方法內部根據這些參數來完成對控件的佈局(就像你在OnGUI中做的一樣)。  如果你打算把自定義控件實現在窗口類內部,你可以使用Partial類來更好的管理你的代碼。 繪製2D內容 繪製圖片  可以使用GUI.DrawTexture來完成對圖片資源的繪製。 繪製基礎圖元 GUI本身並沒有提供繪製基礎圖元的方法,但是可以通過一些方式來封裝出這些方法。  繪製線段:通過一個像素的貼圖資源配合GUI.DrawTexture和矩陣旋轉來完成線段的繪製。  繪製矩形框:通過GUI.Box和樣式設置來封裝出對矩形框和矩形填充框。 資源選擇器 EditorLayout.ObjectField控件提供一個資源選擇邏輯,生成時需要指定某種資源類型。然後你可以拖動該種資源到該控件或點擊控件旁邊的小圓圈進行列表進行選擇。
如何存儲編輯內容 
你可能需要創建一個繼承自SerializedObject的類來保存編輯的數據。繼承自SerializedObject的對象能用於存儲數據而不參與渲染,並可以最終打包到AssetBundle。 針對當前的編輯選項等內容的存儲,可能需要另外一個SerializedObject類(和具體的系統設計相關)。
嚮導式的編輯窗口
在很多情況下可能你都會需要一個有很多參數的編輯面板,然後在編輯結束後有一個按鈕加以確認。這你不用自己來實現,UnityEditor提供了ScriptableWizard來幫助你快捷的進行開發。 他是繼承自EditorWindow的,所以他們的使用是很類似的。不過注意,當你點擊確認按鈕時,OnWizardCreate()會被調用。另外,ScriptableWizard.DisplayWizard可以幫助你生成並顯示出該窗口。
如何擴展INSPECTOR面板
當你在Unity3D中點選一個對象時,Inspector面板會隨即顯示出此對象的屬性。我們可以針對某個類型的對象擴展該面板,這在爲Unity3D開發插件時是非常有用的。
定義INSPECTOR何時被觸發
自定義的Inspector面板需要繼承Editor類。由於功能相對具體,所以你無需定義代碼何時被觸發,對應代碼會在你點擊它所對應的物體時自動執行。 那麼如何定義它所對應的類型呢?只需要在你的類定義之前通過編譯器的命令[CustomEditor(typeof(XXX))]就可以完成這項工作了。
訪問被編輯的對象
在Inspector視圖中,我們經常需要訪問正在被編輯的對象。Editor類的成員變量target正是提供了這一關聯。  儘管如此,需要注意target是一個Object類型的對象,具體使用時可能需要類型轉換(可以使用C#的泛型來避免重複的類型轉換)。
實現你自己的INSPECTOR界面
擴展Editor與擴展EditorWindow唯一的不同在於你需要重寫的是OnInspectorGUI而不是OnGUI。另外,如果你想繪製默認的可編輯項,只需調用DrawDefaultInspector即可。
在SCENE界面定義編輯句柄
當選中一個物體的時候,可能我們希望在Scene視圖裏也能定義一些編輯或展現。這一工作可以通過OnSceneGUI和Handle類來完成。OnSceneGUI用來處理來自Scene視圖的事件,而Handle類用來在Scene視圖實現一些3D的GUI控件(例如控制對象位置的Position控制器)。 具體的使用方式可以參考官方的參考文檔。
一些常用的功能說明
 AssetDatabase.CreateAsset可以幫住你從資源目錄中創建一個資源實例。  Selection.activeObject返回當前選中的對象。  EditorGUIUtility.PingObject用來實現在Project窗口中點擊某一項的操作。  Editor.Repaint用來重繪界面所有的控件。  XXXImporter用來設置某種資源的具體導入設置(例如在某些情況下你需要設置導入的貼圖爲可讀的)。  EditorUtility.UnloadUnusedAssets用於釋放沒有使用的資源,避免你的插件產生內存泄漏。  Event.Use用來標記事件已經被處理結束了。  EditorUtility.SetDirty用來通知編輯器數據已被修改,這樣在下次保存時新的數據將被存儲。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章