技術筆記(10)Unity編輯器擴充套件
-
希望實現的功能或目標:
- 編寫一個編輯器擴充套件功能,用以快速建立Event和Command指令碼
-
學習筆記:
-
CreateScriptWindow類
-
繼承EditorWindow類
-
用兩個常量字串,記錄模板所在的檔案路徑
-
const string EVENTTEMPLATE_PATH = "Assets/Scripts/GameFramework/ReusableCode/Layers/Utility/Editor/EventTemplateScript.txt"; const string COMMANDTEMPLATE_PATH = "Assets/Scripts/GameFramework/ReusableCode/Layers/Utility/Editor/CommandTemplateScript.txt";
-
-
呼叫MenuItem選擇新增按鈕的索引位置
-
[MenuItem("Assets/Create/C# Event Script(Command)")]
-
-
AssetsCreate方法:呼叫GetWindow方法,得到一個當前類名的window,並呼叫這個window的Show方法
-
static void AssetsCreate() { CreateScriptWindow window = (CreateScriptWindow)GetWindow(typeof(CreateScriptWindow), false, "建立C#"); window.Show(true); }
-
-
兩個普通字串
-
string _scriptName; string _description;
-
-
OnGUI方法
-
透過GetPath方法獲取當前所選的目錄
-
在Directory中查詢該目錄是否存在
-
如果存在,則建立一個TextField用來輸入指令碼名。
-
然後建立一個“建立事件”按鈕
-
如果建立成功了,設定要生成的指令碼的路徑,並展示出來
- 檢測輸入的指令碼名是否正確,是否已有同名指令碼並報錯
- 如果都沒問題,把模板裡的內容讀出來,把所有的“My”替換成輸入的指令碼名,並以UTF8的編碼格式寫到新生成的指令碼里
- 重新整理project列表,顯示建立成功的提示資訊
-
-
建立命令指令碼的邏輯同上
-
-
private void OnGUI() { string selectDirPath = GetPath(); if (Directory.Exists(selectDirPath)) { _scriptName = EditorGUILayout.TextField("指令碼名:", _scriptName); if(GUILayout.Button("建立事件", GUILayout.Height(40))) { string path = selectDirPath + "/" + _scriptName + "Event.cs"; EditorGUILayout.LabelField("路徑:", path); EditorGUILayout.Space(); if (!CheckScriptName(_scriptName)) { ShowNotification(new GUIContent("請輸入正確的指令碼名!")); } else if(CheckRepeat(selectDirPath)) { ShowNotification(new GUIContent("當前資料夾下已經有同名指令碼!")); } else { string content = File.ReadAllText(EVENTTEMPLATE_PATH); content = content.Replace("My", _scriptName); File.WriteAllText(path, content, Encoding.UTF8); AssetDatabase.Refresh(); ShowNotification(new GUIContent("Success!")); } } if (GUILayout.Button("建立命令", GUILayout.Height(40))) { string path = selectDirPath + "/" + _scriptName + "Command.cs"; EditorGUILayout.LabelField("路徑:", path); EditorGUILayout.Space(); if (!CheckScriptName(_scriptName)) { ShowNotification(new GUIContent("請輸入正確的指令碼名!")); } else if (CheckRepeat(selectDirPath)) { ShowNotification(new GUIContent("當前資料夾下已經有同名指令碼!")); } else { string content = File.ReadAllText(COMMANDTEMPLATE_PATH); content = content.Replace("My", _scriptName); File.WriteAllText(path, content, Encoding.UTF8); AssetDatabase.Refresh(); ShowNotification(new GUIContent("Success!")); } } } else { EditorGUILayout.LabelField("請在Project皮膚中選擇將要放置指令碼的資料夾"); } }
-
-
CheckScriptName方法
- 用正規表示式記錄命名標準格式
- 對輸入的引數進行檢測,並返回是否符合格式
-
bool CheckScriptName(string scriptName) { Regex regex = new Regex("^[a-zA-Z_][a-zA-Z0-9_]*$"); return regex.IsMatch(scriptName); }
-
CheckRepeat方法
- 以所選路徑為引數,new一個DirectoryInfo物件
- 並用FileInfo陣列存這個DirectoryInfo物件裡獲取到的所有檔案
- 指令碼名字串附上其格式“.cs”
- 遍歷FileInfo陣列,與檔名一一進行對比,有重名則返回true,無則返回false
-
bool CheckRepeat(string selectDirPath) { DirectoryInfo dir = new DirectoryInfo(selectDirPath); FileInfo[] files = dir.GetFiles(); string scriptName = _scriptName + ".cs"; for(int i = 0;i<files.Length;i++) { if (files[i].Name == scriptName) { return true; } } return false; }
-
OnSelectionChange方法
- 呼叫Repaint方法
-
GetPath方法
- 呼叫AssetDatabase類的GetAssetPath方法,以Selection.activeInstanceID作為其引數。從而獲得選中資產的相對路徑
-
private string GetPath() { string assetPath = null; if(assetPath == null || assetPath == "") { assetPath = AssetDatabase.GetAssetPath(Selection.activeInstanceID); } return assetPath; }
-
-
-
實現過程中產生的疑惑:
- 編輯器擴充套件的作用?
- 有哪些實際的應用?
-
對疑惑的解答:
-
其允許我們透過自定義指令碼和外掛來增強和個性化unity編輯器的功能,主要作用有:
- 提高開發效率:自動化處理重複性任務
- 自定義工具和介面:以適應特定的開發需求,提高工作流程和效率和舒適度
- 增強視覺化編輯:繪製輔助圖形、直觀編輯物件屬性
- 整合第三方工具:3d建模、音影片編輯軟體
-
實際應用:
- 可用來執行遊戲特定部分,進行快速測試而無需啟動整個遊戲
- 查詢和替換材質、最佳化紋理等
- 整合Photoshop、Blender等外部工具的功能
-
日期: