本文提供全流程,中文翻譯。 Chinar堅持將簡單的生活方式,帶給世人! (擁有更好的閱讀體驗 —— 高分辨率用戶請根據需求調整網頁縮放比例) |
此教程是在教程(一)基礎上進行擴展:若是不知道如何建立編輯器按鈕,推薦先看教程(一) 數組
Unity3D編輯器擴展介紹、教程 —— 建立菜單項(一)編輯器
咱們在作工程的時候,須要對數據進行操做。函數
爲節省時間,會使用一些快捷鍵,菜單欄上的功能、或是右鍵菜單 工具
這些便捷的功能,都是Unity官方爲了方便咱們對所需數據進行操做。測試
對Unity編輯進行了一些封裝處理,簡化數據操做流程,封裝爲一個按鈕/一個窗口/窗口功能。字體
這些諸如此類的功能就是編輯器的擴展,和封裝spa
功能鍵、Inspector面板、Game視窗等等都是編輯器的功能
注意:編輯器類腳本,必須放在 Assets/Editor 資源目錄中 .net
此文件夾下的腳本只對編輯器進行操做。最後資源打包,Editor文件夾下的全部資源都不會被打包到工程中 翻譯
若是沒有此文件夾,需自行建立:在Project視窗下,右鍵Create - - Folder 3d
ScriptableWizard 是一個編輯器類,繼承自 EditorWindow
從這個類派生來建立一個編輯器嚮導
建立一個顯示器嚮導,調用靜態方法
DisplayWizard <類型>(「標題」, 「第一個按鈕」, 「第二個按鈕」);
便可建立一個 顯示器嚮導
using UnityEditor; //引用Unity編輯器命名空間 using UnityEngine; //引用Unity引擎命名空間 /// <summary> /// 改變全部敵人腳本 /// </summary> public class ChangeAll : ScriptableWizard { public int AddHp = 10; //每次增長血量值 public int Num = 0;//一個數字爲了測試 isValue /// <summary> /// 菜單欄 個人工具 中,建立一個按鈕 /// </summary> [MenuItem("個人工具/修改全部敵人屬性")] static void 修改全部敵人屬性() { //顯示器嚮導 <所管控的類>( 窗口的名字,窗口中按鈕的名字,第二個按鈕的名字 ); DisplayWizard<ChangeAll>("修改全部敵人血量", "確認修改血量", "第二個按鈕"); } }
其中內置了一些固定函數,用來傳遞信息
OnEnable() —————————————————– 腳本有效時就會執行
OnWizardCreate() ————————————— 在 建立 / 第一個 按鈕上點擊時調用
OnWizardOtherButton() ————————— 在 其餘 按鈕上點擊時調用(容許一個動做)
OnWizardUpdate() ————————————– 在嚮導被打開 / 嚮導中數據發生變化時被調用
OnSelectionChange() ——————————— 當選擇發生改變,調用此函數
(此函數在EditorWindow中,而ScriptableWizard繼承自EditorWindow,因此能夠在其中直接調用)
using UnityEditor; //引用Unity編輯器命名空間 using UnityEngine; //引用Unity引擎命名空間 /// <summary> /// 改變全部敵人腳本 /// </summary> public class ChangeAll : ScriptableWizard { public int AddHp = 10; //每次增長血量值 public int Num = 0; //一個數字爲了測試 isValue /// <summary> /// 菜單欄 個人工具 中,建立一個按鈕 /// </summary> [MenuItem("個人工具/修改全部敵人屬性")] static void 修改全部敵人屬性() { //顯示器嚮導 <所管控的類>( 窗口的名字,窗口中按鈕的名字,第二個按鈕的名字 ); DisplayWizard<ChangeAll>("修改全部敵人血量", "確認修改血量", "第二個按鈕"); } /// <summary> /// 固定函數名:窗口開始時執行 /// </summary> void OnEnable() { AddHp = EditorPrefs.GetInt("ChangeAll_health", AddHp); //取值,默認爲初始值 並賦值給AddHp } /// <summary> /// 固定函數名:對應現實嚮導中的第一個按鈕 —— 確認修改血量 /// </summary> void OnWizardCreate() { //進度條 EditorUtility.DisplayProgressBar("修改進度", "0/" + Selection.gameObjects.Length + "完成修改", 1); int count = 0; foreach (var gameObject in Selection.gameObjects) //遍歷選中的物體 { CompleteProject.EnemyHealth health = gameObject.GetComponent<CompleteProject.EnemyHealth>(); //獲取其身上腳本組件 Undo.RecordObject(health, "Change health"); //記錄變量 health 以後作的更改 health.startingHealth += AddHp; //自增 設置的值 //須要修改其餘屬性,本身往下寫 count++; //進度條 EditorUtility.DisplayProgressBar("修改進度", count + "/" + Selection.gameObjects.Length + "完成修改", progress: count / Selection.gameObjects.Length); } EditorUtility.ClearProgressBar();//清除進度條 } /// <summary> /// 固定函數名:對應現實嚮導中的第二按鈕 —— 第二個按鈕 /// </summary> void OnWizardOtherButton() { //彈出通知(新建一個 GUI內容(被選中物體的個數)+「字符」 ) ShowNotification(new GUIContent(Selection.gameObjects.Length + "個元素被選中")); } /// <summary> /// 當屬性值被修改時,每幀調用。 / 當界面開啓時,會調用一次 /// </summary> void OnWizardUpdate() { helpString = null; //每次調用就歸零一次,不然會出現字體不消除的狀況 errorString = null; if (Selection.gameObjects.Length > 0) { helpString = "當前選擇了" + Selection.gameObjects.Length + "個敵人"; //及時更新選擇的數量 } else { errorString = "最少選擇一個啊"; //錯誤提示 } EditorPrefs.SetInt("ChangeAll_health", AddHp); //修改後存入一個值,就是記錄一下。 } /// <summary> /// 當選擇的物體發生改變,調用此函數 /// </summary> void OnSelectionChange() { OnWizardUpdate(); } }
在顯示器嚮導中建立一個進度條
EditorUtility.DisplayProgressBar( 進度條標題,進度信息,進度比例 )
EditorUtility.ClearProgressBar() 調用此函數,進度條纔會被刪除
using UnityEditor; //引用Unity編輯器命名空間 using UnityEngine; //引用Unity引擎命名空間 /// <summary> /// 改變全部敵人腳本 /// </summary> public class ChangeAll : ScriptableWizard { public int AddHp = 10; //每次增長血量值 public int Num = 0; //一個數字爲了測試 isValue /// <summary> /// 菜單欄 個人工具 中,建立一個按鈕 /// </summary> [MenuItem("個人工具/修改全部敵人屬性")] static void 修改全部敵人屬性() { //顯示器嚮導 <所管控的類>( 窗口的名字,窗口中按鈕的名字,第二個按鈕的名字 ); DisplayWizard<ChangeAll>("修改全部敵人血量", "確認修改血量", "第二個按鈕"); } /// <summary> /// 固定函數名:對應現實嚮導中的第二按鈕 —— 第二個按鈕 /// </summary> void OnWizardOtherButton() { EditorUtility.DisplayProgressBar("修改進度", "0/" + Selection.gameObjects.Length + "完成修改", 1); //進度條 int count = 0; //計數 foreach (var gameObject in Selection.gameObjects) //遍歷選中的物體 { CompleteProject.EnemyHealth health = gameObject.GetComponent<CompleteProject.EnemyHealth>(); //獲取其身上腳本組件 Undo.RecordObject(health, "Change health"); //記錄變量 health 以後作的更改 health.startingHealth += AddHp; //自增 設置的值 //須要修改其餘屬性,本身往下寫 count++; //計數自增1 EditorUtility.DisplayProgressBar("修改進度", count + "/" + Selection.gameObjects.Length + "完成修改", count / Selection.gameObjects.Length); //進度條 } //EditorUtility.ClearProgressBar(); //清除進度條(只有調用此方法,進度條纔會刪除) } }
建立一個編輯器窗口,在咱們的Unity編輯器中
GetWindow(bool, 窗口名字)
bool 值爲: false 窗口能夠與其餘窗口合併
bool 值爲: true 窗口獨立,不可合併
如下是我寫的一個簡單的梨子,用於批量修改物體的名稱(選擇物體內數組,並無進行內部處理)
using UnityEditor; //引用Unity編輯器命名空間 using UnityEngine; //引用Unity引擎命名空間 /// <summary> /// 建立一個窗口類 /// </summary> public class ChinarWindow : EditorWindow//繼承自 EditorWindow { string CustomName = "CustomName"; //自定義名字 private int ChinarNum = 0; //空物體數量 /// <summary> /// 建立一個菜單項 /// </summary> [MenuItem("個人工具/顯示新窗口")] static void 顯示新窗口() { ChinarWindow chinar = GetWindow<ChinarWindow>(false, "Chinar窗口"); //獲取到一個窗口,賦值給當前編輯器類的對象 chinar.Show(); //顯示對象的窗口 } /// <summary> /// 此函數中實現編輯器界面的定義/繪製 /// </summary> void OnGUI() { GUILayout.Label("這是Chianr窗口"); //標題 CustomName = GUILayout.TextField(CustomName); //文本框 ChinarNum = int.Parse(GUILayout.TextField(ChinarNum.ToString())); //數字框 //能夠直接判斷按鈕的點擊 if (GUILayout.Button("修改全部物體名字")) { for (int i = 0; i < Selection.transforms.Length; i++) //遍歷選中的元素 { Undo.RecordObjects(Selection.gameObjects as GameObject[], "ChinarWindow_GameObject[]"); //Selection.gameObjects 返回一個GameObject[] ,並記錄鍵(用於回退) Selection.transforms[i].SetSiblingIndex(i); //爲選擇的物體設置下標 Selection.transforms[i].name = CustomName + i; //設置名字+i } } //判斷按鈕的點擊 if (GUILayout.Button("建立多個空物體")) { if (ChinarNum <= 0) //若是數字 小於等於 0 { ShowNotification(new GUIContent("請寫入建立空物體數量")); //提示 輸入 } else //不爲0 { for (int i = 0; i < ChinarNum; i++) //遍歷個數 { Undo.RegisterCreatedObjectUndo(new GameObject(CustomName), "Chinar Create gameobject"); //建立一個名爲 CustomName 的空物體 } } } } }
本博客爲非營利性我的原創,除部分有明確署名的做品外,所刊登的全部做品的著做權均爲本人所擁有,本人保留全部法定權利。違者必究 對於須要複製、轉載、連接和傳播博客文章或內容的,請及時和本博主進行聯繫,留言,Email: ichinar@icloud.com 對於經本博主明確受權和許可以使用文章及內容的,使用時請註明文章或內容出處並註明網址