官方教程:鏈接
EditorLayout API:鏈接
Handles API:鏈接
1.首先來個Inspector面板Editor的實現
要實現一個組件在Inspector中的Editor功能,首先需要寫一個編輯器類:
要點:
1.繼承Editor
2.放在Editor文件夾中
3.在類的頭部寫[CustomEditor(typeof(你要實現編輯的組件的類名))]
4.復寫OnInspectorGUI函數(此函數僅在Inspector刷新時自動調用),然后在函數里實現編輯器功能的拓展實現。例如GUILayout.Label("Hello World");
5.通過target as ‘你的類名’ 來實現引用你要擴展的組件的類的具體對象。
2.GUILayoutOption
EditorGUILayout 與 EditorGUI功能基本差不多,它是EditorGUI的自動布局版本,用它可以快速創建默認UI,若要自定義UI樣式,應該使用EditorGUI並傳入GUIStyle等參數
GUILayoutOption是一種GUI布局方式的設置,常在GUILayout的具體控件中看到,
例如,
的最后一個參數便是一些GUILayoutOption不定參,表示可以有多個設置方案。
注意:GUILayoutOption只是表示是設置方案的意思,並不是代表有GUILayoutOption這種設置方法,GUILayoutOption其實是個空類,
具體的設置方案由具體決定。
例如:
GUILayout.Label("Hello World"), EditorStyles.helpBox);
GUILayout.Label("Hello World")表示在面板上顯示一條內容為“Hello World”的Label,(下圖第一條)
而EditorStyles.helpBox則表示此Label的顯示方式是以幫助框的形式顯示(下圖第二條)
更多的GUILayoutOption:
EditorStyles.boldLabel
EditorStyles.centeredGreyMiniLabel
EditorStyles.radioButton
EditorStyles.whiteBoldLabel
3.GUILayout 之 SelectionGrid
設置一個網格按鈕,並返回按鈕的序號。
string[] text = { "1", "2", "3", "4" };
Debug.Log(GUILayout.SelectionGrid(-1, text, 2) + " has been choose.");
按鈕可以是文字(上面的1,2,3,4四個按鈕),也可以是圖片等。
第一參數的-1表示按鈕哪個被按下,如果為0,則表示第一按鈕顯示為被按下,-1表示沒有。
第三個參數的2表示此網格分為2列,具體如圖:
4.折頁
首先用這句:
showState = EditorGUILayout.Foldout(showState, "State List"); 參數分別為是否打開,顯示標簽的名字
其實折頁就相當於一個toggle按鈕,並不做任何事,只是你按下它,它會返回一個是否折開或者合並的結果,
然后自己再根據這個結果顯示對應內容來達到折頁效果。
if (showState) { GUILayout.Label("內容", EditorStyles.inspectorDefaultMargins); }
// 為了模擬折頁后的子層級的樹狀縮進結構,我門用EditorStyles.inspectorDefaultMargins這中設置來將內容向右縮進。
5.自定義自己的GUIStyle
在2中我們知道了如何用GUIStyle擴展GUILayout的各種控件的樣式,但我們用的都是EditorStyles附帶的風格,
這個EditorStyles是系統用的,我們只能用里面的風格,不能修改(其實也可以改,但改后會將系統其他所以使用該風格的地方都改)。
為了定制我們自己的風格,其實我們可以自己創建一個GUIStyle。
GUIStyle topStyle = new GUIStyle(EditorStyles.centeredGreyMiniLabel); // 這里我用EditorStyles的centeredGreyMiniLabel來初始化我的新風格 topStyle.fontStyle = FontStyle.Bold; // 新Style的字體為粗體 topStyle.fontSize = 20; topStyle.richText = true; // 允許富文本
6.再來個Scene面板的Editor實現
基本與Inspector面板Editor的寫法一樣,只不過Scene面板的更新函數是OnSceneGUI,與之對應的是
Inspector面板的更新函數OnInspectorGUI。
甚至可以在同一個腳本里同時實現Inspector與Scene面板的Editor功能。
要點:
1.在OnSceneGUI()中只能通過Handles來繪制新視圖,如果你想引入GUI的元素哪么就需要使用BeginGUI()和EndGUI()組合的使用。
2.同Inspector一樣,僅在持有該腳本的對象被選擇時才激活。
eg:
void OnSceneGUI() { //得到test腳本的對象 Test test = (Test) target;
//在Scene視圖中,在該對象本身的位置畫一個坐標軸,但畫自身坐標軸的意義不大,因為自身坐標軸在被選中時本來就會畫出來。但可以用來顯示其他對象的坐標軸。
Handles.PositionHandle(fsm.test.transform.position, Quaternion.identity); //在場景中GameObject所在的位置繪制文本框,內容為該GO的坐標 Handles.Label(test.transform.position + Vector3.up*2, test.transform.name +" : "+ test.transform.position.ToString() ); //開始繪制GUI Handles.BeginGUI(); //規定GUI顯示區域 GUILayout.BeginArea(new Rect(100, 100, 100, 100)); //GUI繪制一個按鈕 if(GUILayout.Button("這是一個按鈕!")) Debug.Log("test"); //GUI繪制文本框 GUILayout.Label("我在編輯Scene視圖"); GUILayout.EndArea(); Handles.EndGUI(); }
7.利用Gizmos在Editor里繪制圖形
Gizmos是常見的DebugDraw方式之一,可方便地在Editor里繪制線段,射線,方塊之類的
用法:Gizmos只能用於OnDrawGizmos函數里,該函數跟Start,Update一樣會自動調用
但是一般情況下,繪制函數里的參數只有'center','size'之類的,繪制出來的圖形是沒有角度的,
如果有需要繪制旋轉過的圖形,例如一個跟隨攝影機旋轉的Cube
那么就需要利用Gizmos的重要參數——matirx,
這是Gimos的繪制矩陣,繪制的圖形信息在這里,要縮放,旋轉Gizmos繪制出來的圖形,
只需要改變矩陣即可。
void OnDrawGizmos() { Vector3 size = new Vector3(half.x * 2, half.y * 2, half.z * 2); // 變換矩陣 Matrix4x4 trs = Matrix4x4.TRS(transform.position, transform.rotation, transform.localScale); Gizmos.matrix = trs; // 在該Transform的Vector3.zero處繪制一個位置、角度、縮放均與該Transform一樣的方塊,大小為size Gizmos.DrawCube(Vector3.zero, size); // 復位Gizmos設置 Gizmos.matrix = Matrix4x4.identity; }
8.Editor菜單欄快捷鍵
%代表 Ctrl
#代表 Shift
9.手動將Scene標志為“修改過的”
有時候會動態在Editor腳本里創建對象在Scene里,但是動態創建之后Scene默認是認為場景沒被修改過的,
這個時候是沒法保存場景的,就算你強制Ctrl + S,重載場景后之前動態生成的對象也會丟失(除非你在生成對象后,又手動在場景里做一些修改)
那么我需要手動調用場景管理器里的一個方法,將當前所有打開的場景標志為“臟的”,即被改動過的,這個時候在就可以Ctrl + S保存了。
EditorSceneManager.MarkAllScenesDirty();
同理,如果你通過代碼改過資源,那么也需要手動調用AssetDatabase.Refresh 刷新下編輯器。