上一篇我們講了如何定義菜單按鈕
https://www.cnblogs.com/xiaoyulong/p/10115053.html
這一篇我們講如何定義自己的窗口。
定義窗口我們需要繼承 EditorWindow 類,這個類在 using UnityEditor 命名空間下。
創建窗口有兩個方法可以使用:
1、EditorWindow.GetWindow():創建出來的窗口可通過鼠標動態的延伸窗口。
參數:Type t:窗口類型,注意是一定要繼承自 EditorWindow。
bool utility:窗口是否浮動,如果是就不能內嵌到unity其他窗口中去,如果不是就能嵌入其他窗口。(可以省略,默認為內嵌入式)
string title:窗口的標題,如果為空的話就采用類的名稱來當標題。(可以省略,默認類的名稱)
bool focus:是否可以獲得焦點,如果再次點擊會給窗口一個焦點。
2、EditorWindow.GetWindowWithRect():創建出來的窗口的大小是固定的,無法改變。
參數:Type t:窗口類型,注意是一定要繼承自 EditorWindow。
Rect rect:窗口的大小。
bool utility:窗口是否浮動,如果是就不能內嵌到unity其他窗口中去,如果不是就能嵌入其他窗口。(可以省略,默認為內嵌入式)
string title:窗口的標題,如果為空的話就采用類的名稱來當標題。(可以省略,默認類的名稱)
bool focus:是否可以獲得焦點,如果再次點擊會給窗口一個焦點。
代碼如下:
1 using UnityEditor; 2 using UnityEngine; 3 4 public class EditorWindowTest : EditorWindow 5 { 6 [MenuItem("MyWindow/EditorWindowTest1")] 7 private static void AddWindow1() 8 { 9 EditorWindowTest myWindow = (EditorWindowTest)EditorWindow.GetWindow(typeof(EditorWindowTest), false, "Window1 name", true);//創建窗口 10 myWindow.Show(); 11 } 12 13 [MenuItem("MyWindow/EditorWindowTest2")] 14 private static void AddWindow2() 15 { 16 Rect _rect = new Rect(0, 0, 500, 500); 17 EditorWindowTest window = (EditorWindowTest)EditorWindow.GetWindowWithRect(typeof(EditorWindowTest), _rect, true, "Window2 name"); 18 window.Show(); 19 } 20 }
效果圖:
窗口創建出來了,我們可以使用 GUI 和 GUILayout 控件,還可以使用編輯器專用控件 EditorGUI 和 EditorGUILayout 在 OnGUI() 回調函數中給窗口添加內容,下面就用一個小例子給大家演示下,並介紹下窗口支持的回調函數
代碼:
using UnityEditor; using UnityEngine; public class MyEditor : EditorWindow { [MenuItem("MyWindow/window")] private static void AddWindow() { Rect wr = new Rect(0, 0, 500, 500); MyEditor window = (MyEditor)EditorWindow.GetWindowWithRect(typeof(MyEditor), wr, true, "widow name"); window.Show(); } //輸入文字的內容 private string text; //選擇貼圖的對象 private Texture texture; //繪制窗口時調用 private void OnGUI() { //輸入框控件 text = EditorGUILayout.TextField("輸入文字:", text); if (GUILayout.Button("打開通知", GUILayout.Width(200))) { //打開一個通知欄 this.ShowNotification(new GUIContent("This is a Notification")); } if (GUILayout.Button("關閉通知", GUILayout.Width(200))) { //關閉通知欄 this.RemoveNotification(); } //文本框顯示鼠標在窗口的位置 EditorGUILayout.LabelField("鼠標在窗口的位置", Event.current.mousePosition.ToString()); //選擇貼圖 texture = EditorGUILayout.ObjectField("添加貼圖", texture, typeof(Texture), true) as Texture; if (GUILayout.Button("關閉窗口", GUILayout.Width(200))) { //關閉窗口 this.Close(); } } private void Awake() { Debug.Log("Awake"); } private void Update() { Debug.Log("Update"); } private void OnEnable() { Debug.Log("OnEnable"); } private void OnDisable() { Debug.Log("OnDisable"); } private void OnFocus() { Debug.Log("當窗口獲得焦點時調用一次"); } private void OnLostFocus() { Debug.Log("當窗口丟失焦點時調用一次"); } private void OnHierarchyChange() { Debug.Log("當Hierarchy視圖中的任何對象發生改變時調用一次"); } private void OnProjectChange() { Debug.Log("當Project視圖中的資源發生改變時調用一次"); } private void OnInspectorUpdate() { Debug.Log("窗口面板的更新"); //這里開啟窗口的重繪,不然窗口信息不會刷新 this.Repaint(); } private void OnSelectionChange() { //當窗口處於開啟狀態,並且在Hierarchy視圖中選擇某游戲對象時調用 foreach (Transform t in Selection.transforms) { //有可能是多選,這里開啟一個循環打印選中游戲對象的名稱 Debug.Log("OnSelectionChange" + t.name); } } private void OnDestroy() { Debug.Log("當窗口關閉時調用"); } }
效果圖:
最后介紹兩個API:
fousedWindow(靜態屬性):鍵盤操作的窗口的焦點。鍵盤在對哪個窗口進行輸入或者其他操作,這個靜態變量就是那個窗口。
mouseOverWindow(靜態屬性):鼠標操作的窗口的焦點。鼠標懸停在哪個Window,這個靜態變量就是那個窗口。
除了上面介紹的方法以外,Unity還提供了向導式的編輯窗口 ScriptableWizard,就是提供了一個簡單的窗口模塊,支持我們快速開發
創建函數介紹:
public static T DisplayWizard<T>(string title)
public static T DisplayWizard<T>(string title, string createButtonName)
public static T DisplayWizard<T>(string title, string createButtonName, string otherButtonName)
public static ScriptableWizard DisplayWizard(string title, Type klass, string createButtonName)
函數參數詳解:
string title:窗口標題名稱
string createButtonName:Create按鈕名稱
string otherButtonName: 其他按鈕名稱
Type klass:實現類類型
屬性介紹:
createButtonName:修改 create button 的名稱
otherButtonName: 設置 otherButtonName 的名稱
helpString:允許您設置向導的幫助文本。
errorString:允許您設置向導的錯誤文本。
isValid:允許您啟用和禁用向導創建按鈕,以便用戶不能點擊。
回調函數介紹:
OnWizardUpdate:當向導被打開或只要用戶在向導改變了某些東西時就會被自動的調用。
OnWizardCreate:當用戶在創建按鈕上點擊是調用。
OnWizardOtherButton:當用戶在其他按鈕點擊時,此函數會被調用
案例:
代碼:
1 using UnityEditor; 2 using UnityEngine; 3 4 public class ScriptableWizardTest : ScriptableWizard 5 { 6 #region --變量定義 7 public float range = 500; 8 public Color color = Color.red; 9 #endregion 10 11 #region --自定義函數 12 [MenuItem("MyWindow/Create Light Wizard")] 13 static void CreateWizard() 14 { 15 ScriptableWizard.DisplayWizard<ScriptableWizardTest>("Create Light", "Create", "Apply"); 16 } 17 void OnWizardCreate() 18 { 19 GameObject go = new GameObject("New Light"); 20 Light lt = go.AddComponent<Light>(); 21 lt.range = range; 22 lt.color = color; 23 } 24 void OnWizardUpdate() 25 { 26 helpString = "Please set the color of the light!"; 27 } 28 void OnWizardOtherButton() 29 { 30 if (Selection.activeTransform != null) 31 { 32 Light lt = Selection.activeTransform.GetComponent<Light>(); 33 34 if (lt != null) 35 { 36 lt.color = Color.red; 37 } 38 } 39 } 40 #endregion 41 }
效果圖: