一惋戏、簡(jiǎn)介
????以前一直以為Unity編輯器開(kāi)發(fā)很復(fù)雜,很難他膳。但是自學(xué)了一天之后响逢,慢慢的將一些腳本用Editor來(lái)進(jìn)行封裝,發(fā)現(xiàn)在整體開(kāi)發(fā)上會(huì)方便很多矩乐,很多數(shù)據(jù)龄句、參數(shù)可以進(jìn)行靈活查看以及屏蔽,所以特意做一個(gè)Editor的詳細(xì)教程散罕,分享給別人分歇。
????我將詳細(xì)介紹Editor Windows(窗口)開(kāi)發(fā)、Editor Inspector(屬性窗口)開(kāi)發(fā)欧漱、Editor Hierarchy(右鍵菜單)開(kāi)發(fā)职抡。
二、Windows窗口開(kāi)發(fā)
1误甚、創(chuàng)建一個(gè)Editor腳本
????在Editor文件夾下新建一個(gè)類(TestEditorWindows)缚甩,該類集成EditorWindow,還需要引用UnityEditor命名空間窑邦。
2擅威、了解一些Windwos窗口開(kāi)發(fā)的方法
????創(chuàng)建類完畢之后,在編寫如下代碼:
//1.必須跟類型一樣冈钦,這是窗口的名稱
TestEditorWindows()
{
this.titleContent = new GUIContent('測(cè)試編輯器窗口');
}
//2.這是在哪里創(chuàng)建窗口
[MenuItem('Test/Test窗口')]
static void CreateTestWindows()
{
EditorWindow.GetWindow(typeof(TestEditorWindows));
}
????目前窗口中什么都沒(méi)有郊丛,因?yàn)槲覀冞€沒(méi)開(kāi)始寫控件。
????如果需要在窗口中繪制控件瞧筛,則需要在OnGUI()中去編寫相關(guān)代碼厉熟,在此之前我們需要了解OnEnable()方法。
//窗口啟動(dòng)時(shí)较幌,會(huì)調(diào)用此方法
private void OnEnable()
{
//OnEnable()方法是一個(gè)比較重要的方法揍瑟,在一般的窗口繪制中,可在這里進(jìn)行相關(guān)數(shù)據(jù)的初始化乍炉。
}
//實(shí)時(shí)繪制相關(guān)控件
private void OnGUI()
{
//OnGUI()方法則是實(shí)時(shí)的進(jìn)行控件繪制绢片,窗口控件繪制也就在這里進(jìn)行代碼編寫。
}
了解一些常用的控件了解一些常用的控件
????在編寫想要的窗口時(shí)岛琼,需要了解常用的控件底循,這些控件都是我們非常常用的。值得注意的是不管是在Windows窗口開(kāi)發(fā)還是Inspector窗口開(kāi)發(fā)衷恭,常用的控件基本都在GUILayout和EditorGUILayout這兩個(gè)類中此叠,有些控件兩者都可以,不過(guò)一般都會(huì)用EditorGUILayout珍坊,因情況而定……所以別在開(kāi)發(fā)中炒瘸,網(wǎng)上的資料中有時(shí)用GUILayout延赌,有時(shí)又用EditorGUILayout吱涉。
下面將介紹常用的控件
1.GUILayout.BeginScrollView/GUILayout.EndScrollView
GUILayout.BeginScrollView/GUILayout.EndScrollView這個(gè)控件是添加窗口滾動(dòng)條的莲组,也就是給你這個(gè)窗口添加水平和垂直滾動(dòng)條罗标。
具體使用如下:
????備注:編寫完畢之后丈挟,此時(shí)看窗口是沒(méi)有滾動(dòng)條的樣式的显沈,因?yàn)槔锩婺壳斑€沒(méi)有任何的控件软瞎。在介紹后面兩個(gè)控件時(shí),我們需要說(shuō)明下拉讯,在Unity編輯器中涤浇,如果我們要對(duì)控件進(jìn)行控件的布局,比如有些控件水平顯示魔慷,有些垂直顯示只锭。那么就需要應(yīng)用后面的這兩個(gè)控件,不過(guò)在一些真正的項(xiàng)目開(kāi)發(fā)或者一些公司中院尔,他們都會(huì)基于這兩個(gè)布局控件蜻展,進(jìn)行在封裝一層,以方便靈活使用邀摆。在程序UI界中纵顾,比如UGUI、GUI栋盹、以及一些非Unity的UI控件插件等施逾,都基本上有這種類似的布局。需要注意:這種布局控件贞盯,一般都是配對(duì)出現(xiàn)的音念,比如你用了GUILayout.BeginVertical()后,在后面你必須要有GUILayout.EndVertical()躏敢。否則窗口將繪制不出來(lái)并且提示錯(cuò)誤提示闷愤。這點(diǎn)在編寫復(fù)雜的窗口時(shí),很重要件余,因?yàn)橐徊涣羯窬统霈F(xiàn)錯(cuò)誤讥脐。最好在編寫代碼的時(shí)候,將BeginVertical和EndVertical一起碼出來(lái)啼器,以便到時(shí)候去匹配旬渠。
2、GUILayout.BeginVertical/GUILayout.EndVertical
????該控件是垂直布局控件端壳,也就是說(shuō)在這個(gè)區(qū)域內(nèi)的控件告丢,都將垂直排列。
3损谦、GUILayout.BeginHorizontal/GUILayout.EndHorizontal
????該控件是水平布局控件岖免,在這個(gè)區(qū)域內(nèi)的控件岳颇,都將水平排列。
????在這里在來(lái)一個(gè)小技巧颅湘,給布局添加背景樣式话侧,以及定義寬高,這時(shí)候就可以顯示窗口滾動(dòng)條了闯参。
????備注:當(dāng)窗口縮放到代碼指定的控件寬高時(shí)瞻鹏,窗口會(huì)自動(dòng)顯示滾動(dòng)條,當(dāng)然前提是你在最開(kāi)始前布局了GUILayout.BeginScrollView/GUILayout.EndScrollView鹿寨。
4新博、GUILayout.Button:按鈕
????Button按鈕這個(gè)控件應(yīng)該不需要進(jìn)行介紹了,當(dāng)按下時(shí)脚草,返回true叭披。可在這里寫自己的實(shí)現(xiàn)玩讳,同時(shí)可設(shè)置Button的寬高涩蜘,利用GUILayout.Width和GUILayout.Height,也可以利用GUIContent給按鈕添加提示熏纯,同時(shí)可利用GUIStyle給按鈕添加樣式同诫。
5、GUILayout.Box:Box區(qū)域
????Box控件就是文字框/圖片框了樟澜,指定一塊框误窖,其實(shí)跟Button差不多,只不過(guò)不能進(jìn)行點(diǎn)擊而已秩贰。
6霹俺、EditorGUILayout.LabelField:文本信息
????LabelField控件,就是文本標(biāo)簽了毒费,在這里可以書寫自己的信息丙唧,沒(méi)什么好介紹的。
7觅玻、GUILayout.HelpBox:幫助信息
????HelpBox類似LabelField標(biāo)簽想际,也是文字提示類的,但是它多了幾個(gè)狀態(tài)以及背景框溪厘,選擇不同的狀態(tài)顯示不同的UI胡本。
8、TextArea:文本輸入框
9畸悬、Toggle:?jiǎn)芜x框
????Toggle控件一般用于接收Bool參數(shù)侧甫,比如你有一個(gè)Bool值參數(shù),需要在窗口中顯示出來(lái),那么用Toggle可幫你接收到這個(gè)Bool值信息披粟,這個(gè)也不需要什么介紹彩扔。
10、Slider:進(jìn)度條
????Slider控件僻爽,提供一個(gè)滑輪,指定最大值贾惦、最小值胸梆。那么可滑動(dòng)來(lái)設(shè)置這些值,同時(shí)也可以手動(dòng)設(shè)置须板,類似MonoBehaviour中的Range特性碰镜。
11、EditorGUILayout.EnumPopup:枚舉框
????枚舉控件也是在編寫編輯器中习瑰,使用的比較多的绪颖,比如選擇不同的枚舉,繪制出來(lái)的控件都是不一樣的甜奄,這種情況在我們寫腳本的時(shí)候柠横,可能要定義很多屬性,然后在Inspector屬性窗口中课兄,一下子全部都列出來(lái)了牍氛,但是我們只想根據(jù)不同的狀態(tài),顯示一部分需要的烟阐。枚舉框搬俊、Toggle等控件就有用武之力了,我在編寫編輯器時(shí)蜒茄,經(jīng)常會(huì)用到枚舉或Toggle唉擂,讓Inspector屬性繪制出來(lái)的窗口變得簡(jiǎn)介明了,方便別人使用檀葛。
????這是我基于UGUI在往上封裝一層的KGUI控件玩祟,這是其中的一個(gè)Toggle控件(提前說(shuō)明下,后續(xù)的博客更新屿聋,我將詳細(xì)的介紹我的KGUI控件卵凑,同時(shí)會(huì)詳細(xì)講解UGUI的內(nèi)部一些知識(shí),并且還會(huì)開(kāi)源的哦胜臊,里面集成了類似Excel表格控件勺卢、背包、滾動(dòng)條象对、Button黑忱、下拉框等,都是基于UGUI的RectTransform組件和Image組件,重新編寫一套適合自己項(xiàng)目開(kāi)發(fā)的控件集等等)
12甫煞、DropdownButton:下拉框
DropdownButton可能大家不了解菇曲,也許會(huì)用不到,它的效果跟EnumPopup抚吠,不過(guò)EnumPopup是基于枚舉類常潮,序列化出來(lái)的,而DropdownButton是根據(jù)自定義添加子項(xiàng)楷力。
13喊式、EditorGUILayout.ObjectField 序列化Object物體
????EditorGUILayout.ObjectField組件是用于顯示一些針對(duì)繼承UnityEngine.Object類的相關(guān)組件,比如GameObject萧朝、Transform岔留、Component等相關(guān)組件,或者繼承MonoBehaviour類的腳本检柬。這個(gè)控件在編寫編輯器時(shí)献联,也是經(jīng)常會(huì)用到的一個(gè)東西。
????值得注意的是何址,在Inspector屬性編輯器開(kāi)發(fā)中里逆,有EditorGUILayout.PropertyField組件,它的作用作用跟ObjectField控件是一樣的用爪,只不過(guò)在窗口中运悲,或者有些情況下EditorGUILayout.PropertyField沒(méi)那么方便,但是在Inspector屬性開(kāi)發(fā)中會(huì)方便很多项钮。后續(xù)在詳細(xì)介紹它班眯。
14、GUIContent:控件文字提示
????GUIContent也是一個(gè)非常常用的東西烁巫。給繪制的控件加別名與提示信息署隘,在Inspector屬性繪制中,有一些英文屬性也許看名字不了解他是什么作用亚隙,但是如果用這個(gè)繪制出來(lái)磁餐,就可以很方便它的作用了。大部分控件都可以用這個(gè)阿弃,當(dāng)然也有一些控件是不能用這個(gè)的诊霹。
15、GUIStyle控件樣式
????GUIStyle則是控件的樣式渣淳,比如Label的字體大小脾还,顏色等等。一般采用系統(tǒng)默認(rèn)的入愧,這個(gè)根據(jù)自身情況而定采用自定義的鄙漏。
16嗤谚、根據(jù)數(shù)據(jù)進(jìn)行配置
????明白上述所有的控件之后,就可以在EditorWindows窗口進(jìn)行繪制自己想要的控件了怔蚌,再結(jié)合GUILayout.BeginHorizontal等相關(guān)布局控件巩步,就可以繪制去自己想要的編輯器。
17桦踊、其他控件
????還有一些其他的控件椅野,就不一一列了,基本都是大同小異籍胯。
????這是根據(jù)這些基本控件竟闪,以及一些數(shù)據(jù)類,具體實(shí)現(xiàn)等進(jìn)行自定義繪制一個(gè)配置Json文件的窗口化芒炼,可以很方便的對(duì)Json進(jìn)行增刪改查。
????如果大家看到這里有疑問(wèn)的术徊,請(qǐng)不要在博客中回復(fù)本刽,因?yàn)槲液苌倏床┛偷脑u(píng)論的,可加入我的個(gè)人公眾號(hào)(Hua灬清)赠涮,我會(huì)每周更新一篇博客文檔同步公眾號(hào)文章子寓。
三、Inspector屬性開(kāi)發(fā)
1笋除、簡(jiǎn)介
????Inspector針對(duì)腳本進(jìn)行編輯器繪制斜友,所用的控件跟Windows窗口開(kāi)發(fā)基本一致,只不過(guò)一些繪制方法垃它、初始化等有所區(qū)別鲜屏,下面我將不詳細(xì)的介紹基本控件了,如果不理解的可以看【W(wǎng)indows窗口開(kāi)發(fā)】這一節(jié)国拇。
????我們以下述KGUI_Button類進(jìn)行Inspector屬性繪制洛史。
2、KGUI_Button類介紹
????KGUI是本人根據(jù)UGUI操作的局限性酱吝,基于UGUI的Image組件和RectTransform也殖、Canvas這三個(gè)組件,進(jìn)行了二次封裝务热,后續(xù)博客我會(huì)詳細(xì)的介紹KGUI里面的一些組件忆嗜,同時(shí)會(huì)介紹UGUI一些比較深的知識(shí)。KGUI_Button類也就是類似UGUI的Button崎岂,提供了一些常用的事件捆毫,同時(shí)也提供了針對(duì)物體的按鈕出發(fā),因?yàn)樵趯?shí)際項(xiàng)目開(kāi)發(fā)中冲甘,可能美術(shù)提供的UI是特效冻璃,那么我們知道UGUI中使用特效Button是比較麻煩的响谓,所以一般有些時(shí)候會(huì)用SpriteRenderer,同時(shí)又有些情況Button需要聲音省艳,以及按鈕的激活娘纷、選中組等等很多情況,那么UGUI的Button可能滿足不了那么多情況跋炕,但同時(shí)這些功能又有時(shí)候是通用的赖晶,所以拋離UGUI的Button,基于射線和碰撞體去開(kāi)發(fā)一套全新的辐烂,類似我們熟悉的NGUI遏插。重點(diǎn)介紹KGUI_Button的相關(guān)屬性,不介紹具體的方法實(shí)現(xiàn)和類設(shè)計(jì)纠修,因?yàn)檫@篇不講解具體實(shí)現(xiàn)胳嘲,重點(diǎn)關(guān)注編輯器開(kāi)發(fā),屬性講解只是輔助手段扣草。
2.1了牛、屬性
2.2、事件
2辰妙、KGUI_Button Editor介紹
1)創(chuàng)建一個(gè)Editor類
解析:[CustomEditor(typeof(KGUI_Button))]告訴編輯器鹰祸,編輯哪個(gè)類?[CanEditMultipleObjects] 用于使自定義編輯器支持多對(duì)象編輯的屬性密浑。 然后創(chuàng)建的類集成Editor類蛙婴。注意:同時(shí)才可以在KGUI_Button類中(需要寫編輯器的類)添加[ExecuteInEditMode]特性,這個(gè)特性的意思是在編輯器下尔破,也會(huì)執(zhí)行Awake()街图、Start()、Enable()懒构、Update()台夺。
2)初始化一些數(shù)據(jù)
????類創(chuàng)建完畢后,就可以初始化KGUI_Button的屬性了痴脾,在對(duì)Inspector屬性窗口中進(jìn)行控件的繪制颤介。
?????當(dāng)大家看到上述的一些SerializedProperty定義會(huì)覺(jué)得非常奇怪,為什么要這么寫赞赖,這是序列化屬性滚朵,什么意思呢,就是我們需要序列化出KGUI_Button類中的屬性對(duì)象前域,從而能在后面進(jìn)行繪制出來(lái)辕近。
????在OnEnable()函數(shù)中編寫,對(duì)定義的SerializedProperty字段進(jìn)行賦值匿垄。
????serializedObject.FindProperty(“onClick”);以這個(gè)為例移宅,它的意思是查找序列化對(duì)象下的onClick屬性/字段归粉。上述的工作,初始化常用的屬性也就基本完畢了漏峰。下面在OnInspectorGUI()進(jìn)行繪制糠悼。
3)具體實(shí)現(xiàn)
? ? a.首先要實(shí)現(xiàn)選擇不同的枚舉,繪制出來(lái)的信息是不一樣的浅乔,那么我們可以如下所示這么寫
????這樣子我們就可以根據(jù)選擇不同的枚舉信息進(jìn)行繪制不同的窗口了倔喂。
b.繪制繼承UnityEngine.Object屬性的兩種方式
????同時(shí)我們?cè)谏鲜龅膱D片中,看到很多EditorGUILayout.PropertyField()靖苇,這個(gè)就是繪制出你編輯器的屬性字段席噩,它不用管你是什么類型,只要你對(duì)某個(gè)屬性進(jìn)行序列化查找賦值贤壁,那么它都可以在Inspector窗口中繪制出來(lái)悼枢,當(dāng)然一般像int、bool脾拆、枚舉馒索、vector等都不用這個(gè),因?yàn)閁nity提供了這些基本的控件假丧。同時(shí)只要是你集成UnityEngine.Object的屬性双揪,比如GameObject动羽、Component包帚、Transform等那么你可以不用這么編寫,用我們?cè)凇網(wǎng)indows窗口開(kāi)發(fā)】下的EditorGUILayout.ObjectField()方法也是可以的运吓,這樣的話渴邦,你就不需要定義SerializedProperty字段以及在OnEnable初始化了,不過(guò)在編寫Inspector窗口時(shí)拘哨,還是推薦用EditorGUILayout.PropertyField()
c.繪制非UnityEngine.Object屬性的方式
????當(dāng)然如果是非UnityEngine.Object屬性谋梭,比如Unity的事件(UnityEvent)事件,那么你就不能EditorGUILayout.ObjectField()倦青,因?yàn)檫@是繪制不出來(lái)的瓮床,你只能采用EditorGUILayout.PropertyField()。這點(diǎn)本人在寫Windows窗口時(shí)产镐,嘗試過(guò)隘庄。
四、Hierarchy右鍵菜單開(kāi)發(fā)
在有些情況癣亚,我們需要在Hierarchy郵右鍵時(shí)丑掺,也想出現(xiàn)我們自定義的菜單項(xiàng),應(yīng)該怎么做呢述雾?
[MenuItem(“GameObject/KGUI/KGUI_Toggle(開(kāi)關(guān))”, validate = false, priority = 10)]重要是這行代碼街州,在靜態(tài)方法中兼丰,添加如上述所示,那么在Hierarchy窗口中唆缴,右鍵就可以出現(xiàn)這個(gè)菜單項(xiàng)鳍征,則上述代碼的實(shí)現(xiàn)就是獲取到選中的物體,在這個(gè)物體下生成控件等功能琐谤。