一、簡介
????以前一直以為Unity編輯器開發很復雜,很難。但是自學了一天之后,慢慢的將一些腳本用Editor來進行封裝,發現在整體開發上會方便很多,很多數據、參數可以進行靈活查看以及屏蔽,所以特意做一個Editor的詳細教程,分享給別人。
????我將詳細介紹Editor Windows(窗口)開發、Editor Inspector(屬性窗口)開發、Editor Hierarchy(右鍵菜單)開發。
二、Windows窗口開發
1、創建一個Editor腳本
????在Editor文件夾下新建一個類(TestEditorWindows),該類集成EditorWindow,還需要引用UnityEditor命名空間。
2、了解一些Windwos窗口開發的方法
????創建類完畢之后,在編寫如下代碼:
//1.必須跟類型一樣,這是窗口的名稱
TestEditorWindows()
{
this.titleContent = new GUIContent('測試編輯器窗口');
}
//2.這是在哪里創建窗口
[MenuItem('Test/Test窗口')]
static void CreateTestWindows()
{
EditorWindow.GetWindow(typeof(TestEditorWindows));
}
????目前窗口中什么都沒有,因為我們還沒開始寫控件。
????如果需要在窗口中繪制控件,則需要在OnGUI()中去編寫相關代碼,在此之前我們需要了解OnEnable()方法。
//窗口啟動時,會調用此方法
private void OnEnable()
{
//OnEnable()方法是一個比較重要的方法,在一般的窗口繪制中,可在這里進行相關數據的初始化。
}
//實時繪制相關控件
private void OnGUI()
{
//OnGUI()方法則是實時的進行控件繪制,窗口控件繪制也就在這里進行代碼編寫。
}
了解一些常用的控件了解一些常用的控件
????在編寫想要的窗口時,需要了解常用的控件,這些控件都是我們非常常用的。值得注意的是不管是在Windows窗口開發還是Inspector窗口開發,常用的控件基本都在GUILayout和EditorGUILayout這兩個類中,有些控件兩者都可以,不過一般都會用EditorGUILayout,因情況而定……所以別在開發中,網上的資料中有時用GUILayout,有時又用EditorGUILayout。
下面將介紹常用的控件
1.GUILayout.BeginScrollView/GUILayout.EndScrollView
GUILayout.BeginScrollView/GUILayout.EndScrollView這個控件是添加窗口滾動條的,也就是給你這個窗口添加水平和垂直滾動條。
具體使用如下:
????備注:編寫完畢之后,此時看窗口是沒有滾動條的樣式的,因為里面目前還沒有任何的控件。在介紹后面兩個控件時,我們需要說明下,在Unity編輯器中,如果我們要對控件進行控件的布局,比如有些控件水平顯示,有些垂直顯示。那么就需要應用后面的這兩個控件,不過在一些真正的項目開發或者一些公司中,他們都會基于這兩個布局控件,進行在封裝一層,以方便靈活使用。在程序UI界中,比如UGUI、GUI、以及一些非Unity的UI控件插件等,都基本上有這種類似的布局。需要注意:這種布局控件,一般都是配對出現的,比如你用了GUILayout.BeginVertical()后,在后面你必須要有GUILayout.EndVertical()。否則窗口將繪制不出來并且提示錯誤提示。這點在編寫復雜的窗口時,很重要,因為一不留神就出現錯誤。最好在編寫代碼的時候,將BeginVertical和EndVertical一起碼出來,以便到時候去匹配。
2、GUILayout.BeginVertical/GUILayout.EndVertical
????該控件是垂直布局控件,也就是說在這個區域內的控件,都將垂直排列。
3、GUILayout.BeginHorizontal/GUILayout.EndHorizontal
????該控件是水平布局控件,在這個區域內的控件,都將水平排列。
????在這里在來一個小技巧,給布局添加背景樣式,以及定義寬高,這時候就可以顯示窗口滾動條了。
????備注:當窗口縮放到代碼指定的控件寬高時,窗口會自動顯示滾動條,當然前提是你在最開始前布局了GUILayout.BeginScrollView/GUILayout.EndScrollView。
4、GUILayout.Button:按鈕
????Button按鈕這個控件應該不需要進行介紹了,當按下時,返回true。可在這里寫自己的實現,同時可設置Button的寬高,利用GUILayout.Width和GUILayout.Height,也可以利用GUIContent給按鈕添加提示,同時可利用GUIStyle給按鈕添加樣式。
5、GUILayout.Box:Box區域
????Box控件就是文字框/圖片框了,指定一塊框,其實跟Button差不多,只不過不能進行點擊而已。
6、EditorGUILayout.LabelField:文本信息
????LabelField控件,就是文本標簽了,在這里可以書寫自己的信息,沒什么好介紹的。
7、GUILayout.HelpBox:幫助信息
????HelpBox類似LabelField標簽,也是文字提示類的,但是它多了幾個狀態以及背景框,選擇不同的狀態顯示不同的UI。
8、TextArea:文本輸入框
9、Toggle:單選框
????Toggle控件一般用于接收Bool參數,比如你有一個Bool值參數,需要在窗口中顯示出來,那么用Toggle可幫你接收到這個Bool值信息,這個也不需要什么介紹。
10、Slider:進度條
????Slider控件,提供一個滑輪,指定最大值、最小值。那么可滑動來設置這些值,同時也可以手動設置,類似MonoBehaviour中的Range特性。
11、EditorGUILayout.EnumPopup:枚舉框
????枚舉控件也是在編寫編輯器中,使用的比較多的,比如選擇不同的枚舉,繪制出來的控件都是不一樣的,這種情況在我們寫腳本的時候,可能要定義很多屬性,然后在Inspector屬性窗口中,一下子全部都列出來了,但是我們只想根據不同的狀態,顯示一部分需要的。枚舉框、Toggle等控件就有用武之力了,我在編寫編輯器時,經常會用到枚舉或Toggle,讓Inspector屬性繪制出來的窗口變得簡介明了,方便別人使用。
????這是我基于UGUI在往上封裝一層的KGUI控件,這是其中的一個Toggle控件(提前說明下,后續的博客更新,我將詳細的介紹我的KGUI控件,同時會詳細講解UGUI的內部一些知識,并且還會開源的哦,里面集成了類似Excel表格控件、背包、滾動條、Button、下拉框等,都是基于UGUI的RectTransform組件和Image組件,重新編寫一套適合自己項目開發的控件集等等)
12、DropdownButton:下拉框
DropdownButton可能大家不了解,也許會用不到,它的效果跟EnumPopup,不過EnumPopup是基于枚舉類,序列化出來的,而DropdownButton是根據自定義添加子項。
13、EditorGUILayout.ObjectField 序列化Object物體
????EditorGUILayout.ObjectField組件是用于顯示一些針對繼承UnityEngine.Object類的相關組件,比如GameObject、Transform、Component等相關組件,或者繼承MonoBehaviour類的腳本。這個控件在編寫編輯器時,也是經常會用到的一個東西。
????值得注意的是,在Inspector屬性編輯器開發中,有EditorGUILayout.PropertyField組件,它的作用作用跟ObjectField控件是一樣的,只不過在窗口中,或者有些情況下EditorGUILayout.PropertyField沒那么方便,但是在Inspector屬性開發中會方便很多。后續在詳細介紹它。
14、GUIContent:控件文字提示
????GUIContent也是一個非常常用的東西。給繪制的控件加別名與提示信息,在Inspector屬性繪制中,有一些英文屬性也許看名字不了解他是什么作用,但是如果用這個繪制出來,就可以很方便它的作用了。大部分控件都可以用這個,當然也有一些控件是不能用這個的。
15、GUIStyle控件樣式
????GUIStyle則是控件的樣式,比如Label的字體大小,顏色等等。一般采用系統默認的,這個根據自身情況而定采用自定義的。
16、根據數據進行配置
????明白上述所有的控件之后,就可以在EditorWindows窗口進行繪制自己想要的控件了,再結合GUILayout.BeginHorizontal等相關布局控件,就可以繪制去自己想要的編輯器。
17、其他控件
????還有一些其他的控件,就不一一列了,基本都是大同小異。
????這是根據這些基本控件,以及一些數據類,具體實現等進行自定義繪制一個配置Json文件的窗口化,可以很方便的對Json進行增刪改查。
????如果大家看到這里有疑問的,請不要在博客中回復,因為我很少看博客的評論的,可加入我的個人公眾號(Hua灬清),我會每周更新一篇博客文檔同步公眾號文章。
三、Inspector屬性開發
1、簡介
????Inspector針對腳本進行編輯器繪制,所用的控件跟Windows窗口開發基本一致,只不過一些繪制方法、初始化等有所區別,下面我將不詳細的介紹基本控件了,如果不理解的可以看【Windows窗口開發】這一節。
????我們以下述KGUI_Button類進行Inspector屬性繪制。
2、KGUI_Button類介紹
????KGUI是本人根據UGUI操作的局限性,基于UGUI的Image組件和RectTransform、Canvas這三個組件,進行了二次封裝,后續博客我會詳細的介紹KGUI里面的一些組件,同時會介紹UGUI一些比較深的知識。KGUI_Button類也就是類似UGUI的Button,提供了一些常用的事件,同時也提供了針對物體的按鈕出發,因為在實際項目開發中,可能美術提供的UI是特效,那么我們知道UGUI中使用特效Button是比較麻煩的,所以一般有些時候會用SpriteRenderer,同時又有些情況Button需要聲音,以及按鈕的激活、選中組等等很多情況,那么UGUI的Button可能滿足不了那么多情況,但同時這些功能又有時候是通用的,所以拋離UGUI的Button,基于射線和碰撞體去開發一套全新的,類似我們熟悉的NGUI。重點介紹KGUI_Button的相關屬性,不介紹具體的方法實現和類設計,因為這篇不講解具體實現,重點關注編輯器開發,屬性講解只是輔助手段。
2.1、屬性
2.2、事件
2、KGUI_Button Editor介紹
1)創建一個Editor類
解析:[CustomEditor(typeof(KGUI_Button))]告訴編輯器,編輯哪個類?[CanEditMultipleObjects] 用于使自定義編輯器支持多對象編輯的屬性。 然后創建的類集成Editor類。注意:同時才可以在KGUI_Button類中(需要寫編輯器的類)添加[ExecuteInEditMode]特性,這個特性的意思是在編輯器下,也會執行Awake()、Start()、Enable()、Update()。
2)初始化一些數據
????類創建完畢后,就可以初始化KGUI_Button的屬性了,在對Inspector屬性窗口中進行控件的繪制。
?????當大家看到上述的一些SerializedProperty定義會覺得非常奇怪,為什么要這么寫,這是序列化屬性,什么意思呢,就是我們需要序列化出KGUI_Button類中的屬性對象,從而能在后面進行繪制出來。
????在OnEnable()函數中編寫,對定義的SerializedProperty字段進行賦值。
????serializedObject.FindProperty(“onClick”);以這個為例,它的意思是查找序列化對象下的onClick屬性/字段。上述的工作,初始化常用的屬性也就基本完畢了。下面在OnInspectorGUI()進行繪制。
3)具體實現
? ? a.首先要實現選擇不同的枚舉,繪制出來的信息是不一樣的,那么我們可以如下所示這么寫
????這樣子我們就可以根據選擇不同的枚舉信息進行繪制不同的窗口了。
b.繪制繼承UnityEngine.Object屬性的兩種方式
????同時我們在上述的圖片中,看到很多EditorGUILayout.PropertyField(),這個就是繪制出你編輯器的屬性字段,它不用管你是什么類型,只要你對某個屬性進行序列化查找賦值,那么它都可以在Inspector窗口中繪制出來,當然一般像int、bool、枚舉、vector等都不用這個,因為Unity提供了這些基本的控件。同時只要是你集成UnityEngine.Object的屬性,比如GameObject、Component、Transform等那么你可以不用這么編寫,用我們在【Windows窗口開發】下的EditorGUILayout.ObjectField()方法也是可以的,這樣的話,你就不需要定義SerializedProperty字段以及在OnEnable初始化了,不過在編寫Inspector窗口時,還是推薦用EditorGUILayout.PropertyField()
c.繪制非UnityEngine.Object屬性的方式
????當然如果是非UnityEngine.Object屬性,比如Unity的事件(UnityEvent)事件,那么你就不能EditorGUILayout.ObjectField(),因為這是繪制不出來的,你只能采用EditorGUILayout.PropertyField()。這點本人在寫Windows窗口時,嘗試過。
四、Hierarchy右鍵菜單開發
在有些情況,我們需要在Hierarchy郵右鍵時,也想出現我們自定義的菜單項,應該怎么做呢?
[MenuItem(“GameObject/KGUI/KGUI_Toggle(開關)”, validate = false, priority = 10)]重要是這行代碼,在靜態方法中,添加如上述所示,那么在Hierarchy窗口中,右鍵就可以出現這個菜單項,則上述代碼的實現就是獲取到選中的物體,在這個物體下生成控件等功能。