這是我看到的一片比較完整的講自定義窗口,自定義組件的教程,講的比較詳細,特地轉過來給你們分享一下html
原文地址:https://mp.weixin.qq.com/s/4kporY-PCScRAESy4WSpmA
原文做者:克森
原文出處:微信公衆號克森空間node
利用學到的東西製做本身的工具(自定義的窗口、Inspector、菜單等等)。編程
關於 Unity 內置屬性能夠從到官方文檔中查詢,本篇文章只介紹一些經常使用的內置屬性,以下圖所示:
接下來進行項目設置,建立一個空的 Unity 工程,名字由你來定,文件夾的層級關係以下:
目前還不須要Editor文件夾,可是先建立,日後的教程中會用到。而後再 Scripts 文件夾中建立一個新的 C# 腳本,命名爲「People」,雙擊打開該腳本。數組
AddComponentMenu 屬性容許將一個腳本添加到 Component 菜單中,而後你即可以經過 Component ->(你設置的名字)爲一個選中的遊戲對象建立該腳本,以下所示:
微信
RequireComponent()屬性會自動幫你添加你須要的組件,若是已經存在則再也不重複添加,且不能移除,以下所示:
提示:通過測試,我發現一個問題,若是腳本已經掛在物體身上,而後再修改腳本,爲添加 RequireComponent 屬性的話,徹底不起做用,所以建議你們在用此屬性的時候要注意。ide
ContextMenu()屬性容許添加一個命令到該組件上,你能夠經過右鍵或者點擊設置圖標來調用到它(通常用於函數),且是在非運行狀態下執行該函數,以下所示:
函數
HelpURL()提供一個自定義的文檔連接,點擊組件上的文檔圖標既能打開到你指定的連接,以下所示:
提示:填寫連接時,必定要寫上 http:// 或者 https://,不然將無任何反應。工具
具體操做以下所示:
oop
簡單的分解一下:
1.第9行,咱們使用了 [Header(「BaseInfo」)] 爲其設置了標題(爲「BaseInfo」),如上圖所示。佈局
2.第10行,咱們使用了 [Multiline(5)] 爲其 name 屬性添加了5行輸入,如上圖所示,明顯輸入框變大了。
3.第12行,咱們使用了 [Range(-2,2)] 爲其 age 屬性指定了一個(-2,2)的範圍,而且爲其添加了一個滑塊,如上圖所示。
Tooptip()屬性用於在 Inspector 面板中,當鼠標停留在設置了Tooptip()的屬性添加指定的提示;Space()用於爲在 Inspector 面板兩屬性之間添加指定的距離,以下所示:
仍是使用上一篇的 Unity 工程,而後在 Scripts 文件夾裏建立一個新的 C# 腳本,命名爲「Player」,而後雙擊打開腳本,而後爲其添加以下代碼:
Player 類記錄了 Player 的一些基礎信息,例如:ID、名字、背景故事、生命值、傷害等等。
自定義 Inspector 屬性面板的一些基礎知識,和注意事項以下圖所示:
傳送門: http://www.ceeger.com/Script/Editor/Editor.html
接下來開始製做的咱們本身的 Inpector,對於自定義 Inpector 面板可參考下圖的API:
傳送門:http://www.ceeger.com/Script/EditorGUILayout/EditorGUILayout.BeginVertical.html
如今,請你在 Editor 文件夾中建立一個新的 C# 腳本,雙擊就打開該腳本,併爲其添加以下代碼:
Okey,接下來一一分析一下
默認的界面佈局就是垂直佈局,可是爲了節目效果,咱們仍是把它寫上比較好,設置元素爲垂直佈局需使用這對兄弟來聲明:
EditorGUILayout.BeginVertical(); EditorGUILayout.EndVertical();
在這對兄弟裏面作的佈局都是以垂直方向來排列的。
如上圖所示,整個頁面元素都是以垂直方向來佈局的。
設置元素爲水平佈局需使用這對兄弟來聲明:
EditorGUILayout.BeginHorizontal(); EditorGUILayout.EndHorizontal();
在這對兄弟裏面作的佈局都是以水平方向來排列的。
因爲咱們在上圖圈選的地方使用了 Horizontal 這對兄弟,所以在這對兄弟裏的元素全是以水平方向排列。
使用 EditorGUILayout.Space() 可在兩個元素之間空出一行。
繪製字段用到如下幾個方法:
EditorGUILayout.LabelField()標籤字段 EditorGUILayout.IntField() 整數字段 EditorGUILayout.FloatField() 浮點數字段 EditorGUILayout.TextField() 文本字段 EditorGUILayout.Vector2Field() 二維向量字段 EditorGUILayout.Vector3Field() 三維向量字段 EditorGUILayout.Vector4Field() 四維向量字段
它們的規律就是方法名都是以 Field 結尾,大夥們能夠根據繪製的類型選擇相對應的方法。
通常括號裏面的參數,第一個爲繪製該字段的名字(string 類型),第二個爲繪製該字段的值,以下所示:
1 爲標籤字段
2 爲整形字段
3 爲文本字段
4.爲文本區域
滑塊:EditorGUILayout.Slider()
EditorGUILayout.Slider()用於繪製一個滑塊,從上可知:
第一個參數是滑塊的名字
第二個參數是滑塊要改變的值
第三和第四個參數是滑塊的範圍
效果以下圖所示:
進度條:EditorGUI.ProgressBar()
EditorGUI.ProgressBar()用於繪製一個進度條,從上可知:
第一個參數是設置進度條的大小,類型是一個 Rect。
第二個參數是設置顯示的值,
第三個參數是設置進度條的名字
提示:
1.第一個參數,咱們使用了 GUILayoutUtility.GetRect() 工具類的 GetRect()方法返回一個設置好的矩形框,在案例裏咱們設置了一個 50*50 大小的矩形框。
2.第二個參數,咱們使用 player.health / 100.0f。那是由於進度條的最大值爲1,若是不除100的話,當滑塊的值爲1時,進度條便填滿了,所以咱們想讓值與進度條的比例同步,那就除100吧(語文很差,不知道解釋得如何)。
效果圖:
幫助框:EditorGUILayout.HelpBox()
EditorGUILayout.HelpBox()用於繪製一個盒子(也能夠看做矩形框),而後再盒子的裏面顯示提示信息,從上圖可知:
第一個參數是傳入提示信息
第二個參數是提示信息的類型
效果圖:
錯誤類型
正常類型
警告類型
在以前的項目中,找到 Editor 文件夾,而後建立一個新的 C# 腳本,命名爲「MyFirstWindow」,而後雙擊打開腳本,添加以下代碼:
傳送門:http://www.ceeger.com/Script/EditorWindow/EditorWindow.html
傳送門:http://www.ceeger.com/Script/GUILayout/GUILayout.html
以上是咱們這個案例中主要用到的幾個類。
屬性
首先聲明瞭三個變量:
設置窗口的名字
如代碼註釋所示,利用構造函數來設置窗口的名字。比較陌生的是 titleContent屬性 和 GUIContent 類,簡單瞭解以下圖所示:
GUIContent 界面內容類
titleContent 屬性
這個構造函數所產生的做用以下圖所示:
設置窗口的名字
這個函數用於在菜單欄上添加一個打開該窗口的的菜單選項。比較陌生的是 [MenuItem()] 屬性 和 GetWindow()函數,簡單瞭解以下圖所示:
[MenuItem()] 屬性須要注意的兩點(上圖也有提示):
1.必須是放在 Assets / Editor 文件夾下的類,且使用了 using UnityEditor
2.調用的函數必須是靜態函數(static)
該函數就是用於返回一個窗口對象(就是打開一個窗口)。
繪製窗口元素須要在 OnGUI() 函數裏面設計,接下來咱們一一分解。
步驟:
1.GUILayout.Space(10),這個有說過,讓兩個元素之間空十個像素之間的距離
2.GUI.skin.label.fontSize 、GUI.skin.label.alignment 用於設置標題的字體大小和對齊格式,具體從下圖中瞭解:
對於 GUI.skin API 裏面沒有列出一些關於皮膚的屬性,可是大夥們能夠經過在Assets 菜單下右鍵 Create => GUI skin,以下圖所示:
想對應的屬性全在裏面
3.利用 GUILayout.Label() 來繪製標題
整個代碼的效果以下圖所示:
好吧,似曾相識,所以不在贅述,效果以下所示:
在這段代碼中,比較陌生的也就是 EditorSceneManager.GetActiveScen().name,咱們先看下圖進行簡單的瞭解:
其實就是返回當前編輯的場景信息(也就是返回 Scene 類型參數),而後利用 name 屬性獲取場景的名字,效果以下:
這段代碼主要就是利用 System.DateTime.Now 獲取當前時間,而後經過 GUILayout.Label() 把當前時間顯示出來,對於 System.DateTime.Now 可從下面連接去了解:
https://msdn.microsoft.com/zh-cn/library/system.datetime.now(v=vs.110).aspx
效果圖以下:
#####繪製對象槽
咱們先看看API:
從上圖可知:
1.第一個參數用於設置卡槽的標題名字
2.第二個參數用於設置字段顯示的物體
3.第三個參數用於設置顯示的類型
4.第四個參數用於設置是否容許指定場景中的物件
效果以下:
好的,這段代碼咱們也介紹過了,直接上效果圖:
其實很簡單,不外乎就是添加一個按鈕唄。在咱們的代碼中,用了一個 if 判斷語句來判斷,當咱們點擊該按鈕時所觸發的事件(該函數的返回值是一個 bolol 類型),在代碼中克森也上好備註了,所以也沒有什麼難的,直接上效果圖:
#####SaveBug() 函數
其實這個函數所作的事情也很簡單,就是把咱們設置好的一些參數保存到一個文本文件(.txt文件)上,僅此而已。
步驟以下:
1.第一行,利用 Directory 類建立一個目錄
2.建立一個寫入流類(StreamWriter)
3.而後把設置好的各個參數寫入文件中
還不瞭解 C# 文件操做的朋友,是時候返回去補補了,API 連接以下:
https://msdn.microsoft.com/zh-cn/library/system.io.directory(v=vs.110).aspx
https://msdn.microsoft.com/zh-cn/library/system.io.streamwriter(v=vs.110).aspx
具體操做以下所示:
而後你便能在 Assets 文件夾看到以下圖所示信息:
其實這個函數所作的事情跟上面那個函數作的事情同樣同樣的,不外乎就對了一行代碼,而這行代碼即是得到遊戲屏幕截圖,僅此而已,經過下面 API 去了解:
具體操做和上面同樣同樣的,只不過多了同樣圖片,僅此而已,以下圖所示:
好吧,至此咱們的這篇文章就結束了。
因爲過久不更新,以前的項目不知道跑哪兒去了。讓咱們從新建立一個新的項目,命名爲「MyHandles」。而後建立三個文件夾,以下圖所示:
接下來在Scripts文件夾中,建立一個C#腳本,並命名爲「MyHandles」;而後在Editor文件夾中再建立一個C#腳本,命名爲「HandlesInspector」;而後在將下面的小圖標保存到Img文件夾中:
好了準備工做就緒,開始碼了個碼。
在這篇教程中,咱們主要用到 Handles 這個類,一下是該類的基本介紹,克森會挑出幾個比較經常使用的屬性和方法來製做一下簡單的東西,其它屬性和方法大夥們能夠自行去嘗試嘗試:
API傳送門:http://www.ceeger.com/Script/Handles/Handles.html
首先打開咱們的 MyHandles.cs 腳本,爲其添加一個變量:
而後打開 HandlesInspector.cs 腳本,添加以下代碼:
將這兩個腳本保存,回到Unity中建立一個空物體,併爲其添加 MyHandles.cs 腳本:
此時咱們觀察場景,除了場景中出了 「MyHandles」 幾個字外,彷佛啥事兒也沒發生,不急,讓咱們來調整調整 Area Radius 參數的值,便能看到以下效果:
代碼很簡單,註釋也給你們弄上了,相信你們都能看懂吧。仍是不太懂的能夠多看看API:
做用:這個東西是否是有點類型於碰撞體的那個框框啊,這玩意多用於製做AI,用於判斷和指定UI影響範圍用的。
打開 MyHandles.cs 腳本,添加以下變量:
而後爲 HandlesInspector.cs 腳本添加以下代碼:
這段代碼呢也不難於理解,就是參數多了點
PS:因爲中文版的介紹不全,因此補了一張官方的API。
做用:多用於繪製一些自定義的操做,好比Unity的粒子系統就用到了好多自定義的操做柄,好比粒子系統的Shape參數就用到了該函數的第五個參數來繪製:
打開 MyHandles.cs 腳本,添加以下變量:
而後爲 HandlesInspector.cs 腳本添加以下代碼:
回到場景中,此時大夥們會碰到這樣的問題:
別擔憂,那是由於你沒有設置 nodePoints 屬性,全部該函數訪問到一個空的數組,所以便報出了老司機錯誤。以下圖所示便OK:
這段代碼簡單了吧,也就兩個參數,若是仍是不清楚的小夥伴能夠多嘗試嘗試。
做用:這個能夠用在AI上面,而後爲每個AI添加一個位置操做柄,這樣好像看上去方便很多吧?
打開 MyHandles.cs 腳本,添加以下變量:
而後爲 HandlesInspector.cs 腳本添加以下代碼:
一樣的,會出現上面相似的錯誤,甚至更加嚴重,Scene視圖直接白屏!!使用一樣的解決方法便可,以下所示:
PS:nodePointsRotation的個數要與nodePoints的個數要相等或者小於nodePoints。
這段代碼一樣很簡單了吧,也是兩個參數,若是仍是不清楚的小夥伴能夠多嘗試嘗試。
作一個操做,看看大夥們能不能看懂我想表達的意思:
是否是感受像是靜止通常,一動不動的呢?下面修改一下代碼:
此時,你會看到以下的錯誤,不要慌張,咱們只有越到錯誤,解決多了,那之後越到錯誤就不是什麼可怕的事情了:
相信不少人都知道這個是什麼錯誤吧,那是由於由三維向量轉爲四元素W的值不能爲0,所以咱們只要把W設置爲1便可,以下所示:
這個操做呢,主要是幫你們找出一些開發過程當中容易遺漏的錯誤,還有一個目的就是讓座標軸跟隨着旋轉而旋轉(由於第二個參數是位置操做柄的旋轉方向嘛,我把它改成了咱們設置好的旋轉方向,所以位置操做柄便能跟隨着咱們的旋轉而旋轉了)。
爲 HandlesInspector.cs 腳本添加以下代碼:
此時回到場景中便能看到以下所示:
這段代碼呢,也很簡單,可能有點不明白的也就是 Mathf.Repeat()函數,這個簡單,看下圖便能明白:
其實這樣作的緣由大夥們都知道,就是爲了防止下標越界。
打開 MyHandles.cs 腳本,添加以下變量:
而後爲 HandlesInspector.cs 腳本添加以下代碼:
其實也很容易理解,就是當showNodeHandles爲false時便不執行 if 代碼塊裏的代碼,所以便沒法繪製出位置操做柄和旋轉操做柄咯,最終的效果以下:
爲 HandlesInspector.cs 腳本添加以下代碼:
回到場景便能看到以下圖所示的界面:
這段代碼呢,其實也很簡單,不過是運用了兩對函數。
第一對爲:Handles.BeginGUI() 和 Handles.EndGUI()。這對函數表名你想要在Scene視圖下繪製東西。
第二對爲:GUILayout.BeginHorizontal() 和 GUILayout.EndHorizontal()。這對函數代表你想要以水平方向繪製東西。相信第二對函數大夥們都不陌生吧,記得在《Unity Editor 基礎篇(三):Editor Window》中有介紹過。
裏面的邏輯代碼也很簡單,那就是繪製一個按鈕,當我點擊時讓 MyHandles.shoNodeHandles的值取反(也就是原來爲true,點擊後取反,便爲false)。
補充:在第一對函數裏得操做和自定義窗口裏得操做幾乎相同,你們能夠參考下面得API去嘗試嘗試:
http://www.ceeger.com/Script/GUILayout/GUILayout.html
這個插件就用到了今天咱們學到的東西製做而成的:
好了,差很少就介紹到這裏吧
在以前的項目或者新建的項目中建立以下目錄結構:
若是是新的項目,只需建立Scripts和Gizmos就好。
該文章用的到API:
傳送門:http://www.ceeger.com/Script/Gizmos/Gizmos.html
由上圖可知,Gizmos是用於在場景視圖可視化調試或輔助設置用的。
須要注意的是因此Gizmos的繪製必須在腳本的OnDrawGizmos或OnDrawGizmosSelected裏編寫,所以咱們的第一步即是在腳本中添加這兩個函數。
在Scripts文件夾中建立一個C#腳本,命名爲:「MyGizmos」,雙擊打開腳本,碼入以下代碼:
讓咱們來測試一下:
咦,感受不對啊,感受不是每一幀都在調用啊!克森作了個測試,若是你在Scene視圖下不作任何錯誤(鼠標滑動也不能調用這兩個函數),這兩個函數都沒有調用(看來官方文檔說得不徹底啊!!)。
無論了,總之大夥們知道是這麼一回事兒就好了。
PS:必須於Scene視圖下,於Game視圖下不起做用。
接下來爲「MyGizmos.cs」腳本添加以下代碼:
好,如今回到場景視圖下,以下圖所示操做:
哦豁,咱們的線框球體便出來了,是否是很簡單啊。
代碼分析:
該函數的第一個參數是該線框球體的中心點位置,它是一個Vector3類型。
第二個參數是該線框球體的半徑大小,它是一個float類型。
接下爲咱們的腳本添加以下代碼:
好,如今回到場景視圖下,以下圖所示操做:
哦豁,咱們的線條便出來了,是否是很簡單啊。
代碼分析:
上圖已經解釋得很是清楚,兩個參數表示:從from起點到to位置繪製一條線。
所以第一個參數就是起點的位置,第二個參數就是指定的位置。
上面代碼的意思就是當前的位置朝 Z-軸 正方向根據 size 的值擴大。
接下來爲咱們的腳本「MyGizmos.cs」添加以下代碼:
好,如今回到場景視圖下,以下圖所示操做:
如上圖所示,咱們經過for循環調用Gizmos.繪製出了5個實心球體。
代碼分析:
由上圖可知。第一個參數是繪製該球體的中心點的位置,第二個參數是該球體的半徑。
所以在咱們的代碼中,利用for循環依據nodePoints參數建立多個球體,在上面的案例中克森建立了5個球體,設置它們的半徑爲0.5(大夥們也能夠添加一個參數,進行動態操做半徑值)。
因爲繪製的東西都是一個色,很差辨別,大夥們能夠添加以下代碼:
添加後的效果:
咱們的球體變成了藍色,咱們的線條編程了紅色,未設置的線框球體仍是默認的白色。
PS:Gizmos.color = Color.blue,若是後續沒有從新指定繪製的顏色,則使用最後一次設置的顏色。
接下來爲咱們的腳本「MyGizmos.cs」添加以下代碼:
回到場景中看看有什麼效果:
好了,從上圖中你們也知道咱們添加的這段代碼的意思了吧。很簡單,就是將這些球體給鏈接起來。
尷尬了,發現最後要將的東西已經在前面暴露出來了。。。就是下圖的這個東西:
相信這個東西大夥們都知道怎麼設置吧,不過爲了該文章的完整性,咱們仍是來操做一遍:
好了,這個是手動設置的,那麼代碼中又是如何設置的呢?
請你們添加以下代碼:
回到場景中,看看有什麼效果發生。
咦,沒有什麼事情發生啊!!!
哦,原來是找不到圖片資源。如上圖所示,這就是爲何文章的開頭讓大夥們建立 Gizmos 文件夾的緣由。如今將一張你喜歡的圖標,命名爲:「icon.jpg」放入Gizmos文件夾中。
PS:圖片的命名必定要與代碼中的第二個參數的名字同樣。
####準備工做
建立一個新的工程或者用上一篇的工程均可以(克森是新建的工程),而後在Scripts文件夾中建立兩個C#腳本,分別命名爲:「Persion.cs」和「ShowPersionInfo.cs」,以下圖所示:
而後在Editor文件夾中建立一個名爲「PersionPropertiesDrawer.cs」的腳本,具體以下圖所示:
首先,打開咱們得「Persion.cs」腳本,爲其添加以下代碼:
這段代碼不用解釋了吧,就是一個普通得類和枚舉。接下來爲咱們的「ShowPersionInfo.cs」腳本添加以下代碼:
爲何要這樣呢?相信大夥們都知道,要想給一個遊戲對象掛上腳本,那麼該腳本就必須繼承自 MonoBehaviour 。大夥們能夠將「Persion.cs」掛到遊戲對象上,便會出現以下圖所示:
因此「ShowPersionInfo.cs」僅僅就是一個輔助類,做用就是將咱們的「Persion.cs」能掛到遊戲對象上。
好了,接下來讓咱們建立一個空的遊戲對象,而且命名爲「Persion」,而後爲其添加「ShowPersionInfo.cs」腳本:
這什麼都沒有啊!!原來,咱們漏掉了一段代碼,接下來讓咱們爲其補上:
原來呀,要想將一個普通的類裏的屬性在Inspector面板中顯示出來,那麼必須將這個普通的類序列化。
好了,讓咱們回到 Unity 中,看看發生了什麼變化。
Perfect!Persion類中的屬性成功的顯示在了Inspector面板上。
好,讓咱們簡單的瞭解一下,什麼是序列化,以下圖所示:
(圖片來源於百度百科)
簡單的理解就是,序列化類的時候是從屬性讀取值以某種格式保存下來,將其傳輸到另外一個地方去。那麼呢,這個過程是交給Unity引擎來實現的,簡單的瞭解就好了(也就是會用就好了)。
接下來就是本篇教程的核心了!!!
首先打開咱們的「PersionPropertiesDrawer.cs」腳本,爲其添加以下代碼:
讓咱們的「PersionPropertiesDrawer.cs」繼承自PropertyDrawer類,而後重寫 OnGUI 和 GetProperties 函數。
添加 [CustomPropertyDrawer(typeof(Persion))],指定該類是用於自定義屬性的繪製。
接下來讓咱們來測試一下這些方法傳入的參數都是作什麼的,爲咱們的腳本添加以下代碼:
好,如今回到Unity看看測試的數據:
從上面的數據能夠看出以下幾點:
1.OnGUI 和 GetPropertyHeight 裏的 property 參數是同一個參數。該參數裏存放的是 Persion 裏的屬性信息。
2.OnGUI 和 GetPropertyHeight 裏的 Label 參數也是同一個參數,該參數裏存放的是 Persion 類的類名。
3.position參數指的是須要在Inspector面板中繪製的區域信息,能夠從下面兩張圖中簡單的瞭解一下:
PS:爲了測試,註釋了一些代碼,而且添加了一個2D剛體組件。
對了還有一個地方遺漏掉了,那就是在Inspector面板中的一行高度爲 16 。咱們能夠從下圖中得知。
好了,接下來就讓咱們來繪製咱們Persion的屬性吧。咱們的目標以下圖所示:
下面看一看咱們的分析圖:
好了,接下來就開始碼咱們的代碼,打開「PersionPropertiesDrawer.cs」,爲其添加以下代碼:
上面的代碼呢,都有分析過了。也許會有一些小夥伴在兩個地方上頭暈,也就是【獲取對應的序列化屬性】和【繪製屬性】這兩個地方上弄不明白。其實很簡單,從下面兩張圖中即可理解:
好了,讓咱們回到Unity中,看看咱們的效果實現了沒:
好的,很是完美的實現了。
至此,該篇文章就已經弄完了。
大夥們還記得《Unity Editor 基礎篇(一):Build-In Attribute》裏所說的東西嗎?以下圖所示:
建立一個新的工程或者用上一篇的工程均可以(克森用的是原來的工程),而後在Scripts文件夾中建立兩個C#腳本,分別命名爲:「ReadOnlyAttribute.cs」和「Test.cs」,以下圖所示:
而後在Editor文件夾中建立一個名爲「ReadOnlyAttributeDrawer.cs」的腳本,具體以下圖所示:
首先,打開咱們得「ReadOnlyAttribute.cs」腳本,爲其添加以下代碼:
這段代碼很簡單,就是讓咱們的「ReadOnlyAttribute」類繼承自「PropertyAttribute」類,該類的解釋以下圖所示:
因此呢,由上圖便能知道咱們接下來要作的事情了吧,那就是讓咱們的「ReadOnlyAttributeDrawer」類繼承自PropertyDrawer類,而後重寫OnGUI和GetPropertyHeight方法,以下圖所示:
上圖的代碼在上一篇都有講解過,所以這裏再也不作過多的贅述。
好的,接下來繼續爲咱們的「ReadOnlyAttributeDrawer.cs」的OnGUI方法添加以下代碼:
在上面的代碼中,咱們使用到了一個名爲「SerializedPropertyType」的枚舉,它存放的是序列化屬性的類型,它包含的類型不少,可是在該篇文章中咱們只使用到了這幾個,感興趣的同窗看能夠去嘗試其它類型。
咱們使用該枚舉爲value獲取相對應類型的值,而後使用一個Label在Inspector面板中繪製出來(\t爲製表符,爲了美化顯示)。
好了,接下來打開咱們的「Test.cs」腳本,添加以下代碼:
如今,讓咱們回到Unity中查看一下效果:
這個。。。是否是很簡單呀。接下來讓咱們製做一個帶有參數的。
讓咱們打開咱們的「ReadOnlyAttribute.cs」,添加以下代碼:
再讓咱們爲「ReadOnlyAttributeDrawer.cs」的OnGUI函數添加以下方法:
上面的代碼相信大夥們都能看懂,惟一有點迷惑的可能就是 attribute 屬性了,其實它就是咱們經過 [CustomPropertyDrawer(typeof(ReadOnlyAttribute))] 傳過來的ReadOnlyAttribute類,所以克森Debug了它的類型名字,接下來讓咱們看看打印出來的信息:
好的,就是咱們的 ReadOnlyAttribute 類。對了克森打印了 myAttribute.textColor 的值,是爲了測試值是否正確的傳入。
好了,接下來開始測試,讓咱們爲咱們的「Test.cs」腳本添加以下代碼:
從上圖可知,其實[ReadOnly(參數)] 傳入的參數對應的就是咱們ReadOnlyAttribute類的構造函數須要傳入的參數。
好了,接下來讓咱們回到Unity中查看一下效果:
好了,大夥們能夠看到,值已經完美的傳入了,效果並非完美指望的那樣。可是咱們的 My Int 的 Apha 值起做用了。
克森對於這個Bug弄了一個晚上,最後發現原來是Unity5.x出的BUG,總之克森今晚把Unity5.x版本都試得差很少了,仍是一個鳥樣,最後Unity4.6版本妥妥得實現了咱們想要得效果,下面有兩張圖,一張是克森試過得版本,一張是Unity4.6實現得效果圖:
(試過的版本)
(Unity4.6版本的效果)
好了,今天的教程就到這裏吧
建立一個新的工程或者用上一篇的工程均可以(克森用的是原來的工程,由於這一篇的內容和上一篇的內容很相似),而後在Scripts文件夾中建立兩個C#腳本,分別命名爲:「DrawerImageAttribute.cs」和「Test.cs」,以下圖所示:
而後在Editor文件夾中建立一個名爲「DrawerImageAttributeDrawer.cs」的腳本,具體以下圖所示:
首先,打開咱們得「DrawerImageAttribute.cs」腳本,爲其添加以下代碼:
這段代碼很簡單,就是讓咱們的「DrawerImageAttribute」類繼承自「PropertyAttribute」類,上一篇已經講過,不瞭解的同窗能夠去看《Unity Editor 基礎篇(七):Property Attributes》
接下來,打開咱們的「DrawerImageAttributeDrawer.cs」腳本,爲其添加以下腳本:
上圖的代碼除了紅色框框裏的東西,其它的在上一篇都有講解過,所以這裏再也不作過多的贅述。
好了,讓咱們來分析分析 DecoratorDrawer 類是個什麼東西,首先從字面上的意思就是:裝飾繪製者。意味着它是用於裝飾的。接下來讓咱們看看它的源碼:
從源碼中咱們知道,它其實和上一篇的PropertyDrawer類差很少,都是繼承自 GUIDrawer。只不過他的 OnGUI 方法的參數比 PropertyDrawer 的 OnGUI 方法的參數好了兩個,僅此而已。
接下來讓咱們爲「DrawerImageAttributeDrawer.cs」添加以下代碼:
上面的代碼應該不難理解吧,就是判斷圖片是否存在,若是不存在就去Resources文件夾裏讀取對應的圖片,而後調用 GUI.DrawTexture(position, image); 在Inspector面板中繪製該圖片。
所以,接下來的操做相信大夥們都知道了吧。那就是建立Resources文件夾,而後將圖片放入該文件夾中,修改相對應的名字,搞定!
接下來,讓咱們回到Unity中查看效果:
咦,怎麼回事兒,怎麼那麼難看?看到這裏,相信看過上一篇文教的夥計們應該知道怎麼作了吧?那就是修改咱們 GetHeight() 方法的返回值就好了呀。
讓咱們回到咱們的「DrawerImageAttribute.cs」腳本中,爲其添加以下代碼:
接着回到「DrawerImageAttributeDrawer.cs」中,添加以下代碼:
好了,接下來打開咱們的「Test.cs」腳本,添加以下代碼:
如今,讓咱們回到Unity中查看一下效果:
這…你坑我?不急不急,克森是故意這麼作的,錯誤見多了那就不是錯誤了。
好,讓咱們來解決這個錯誤。接下來爲咱們的「DrawerImageAttributeDrawer.cs」腳本添加以下代碼:
而後回到Unity中,看看測試的數據,分析出錯緣由:
從上圖中,咱們能夠看出,該腳本先調用的是 GetHeight() 方法,所以當咱們在 GetHeight() 方法中使用 _attribute.height 的時候便會報空指針的錯誤,由於此時的 _attribute 尚未初始化,所以讓咱們添加以下代碼:
好了,接下來回到Unity中查看效果:
Perfect,漂亮的完成了。
好了,《Unity Editor 基礎篇》系列結束了!!!太棒了