在開始今天的編輯器擴展之前,先說一下unity的一大基類的,可能所有的unity程序員都熟悉MonoBehaviour 和Editor。但是unity其實還為我們準備了兩個很厲害的類,它們分別是ScriptableObject和EditorWindow。
ScriptableObject
首先聊聊ScriptableObject類,它可以用于生成一個.asset文件,我稱之為一個數(shù)據容器,用來儲存序列化和反序列化的數(shù)據。一些簡單的數(shù)據也可以不用xml或者josn儲存啦。


上面的圖片可以看到,我們生成了一個.asset文件,點擊它可以在inspector面板上面顯示相關數(shù)據。
EditorWindow
現(xiàn)在我們來聊聊EditorWindow,就像圖片顯示的情況一樣,雖然我們可以點擊.asset文件然后在inspector面板上面修改和查看數(shù)據,但是有一個問題就是當項目越來越大的時候每次要修改數(shù)據都要在Project里面慢慢去找文件非常麻煩。所以我們可以考慮擴展編輯器窗口。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.Linq;
namespace MyUtility
{
/// <summary>
/// 顯示 查找的 第一個 ScriptableObject
/// </summary>
public abstract class ScriptableObjectBrowserEditorWindow<T> : EditorWindow where T : ScriptableObjectBrowserEditorWindow<T>
{
protected abstract string FileName { get; }
Object settings = null;
Editor editor = null;
Vector2 scrollPos;
public static void OpenWindow(string windowName)
{
T window = GetWindow<T>(windowName);
window.position = new Rect(Screen.width / 2, Screen.height / 2, 500, 500);
window.Show();
}
Object[] getProjectObjs(string filter)
{
string[] guids = UnityEditor.AssetDatabase.FindAssets(filter);
string[] paths = new string[guids.Length];
Object[] returnObjs = new Object[guids.Length];
for (int i = 0; i < guids.Length; i++)
{
paths[i] = AssetDatabase.GUIDToAssetPath(guids[i]);
returnObjs[i] = AssetDatabase.LoadAssetAtPath<Object>(paths[i]);
}
return returnObjs;
}
protected void findAsset()
{
Object[] objs = getProjectObjs("t:" + FileName); // 一定要記住這里要加上"t:",不要直接用文件名稱,
if (objs.Length > 0) // 不然得到的是繼承ScriptableObject的腳本,而不是.asset文件
{
settings = objs[0];
editor = Editor.CreateEditor(settings);
}
}
protected virtual void OnEnable()
{
findAsset();
}
void OnGUI()
{
scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
if (GUILayout.Button("ReFresh", GUILayout.Width(100)))
{
findAsset();
}
EditorGUILayout.Space();
EditorGUILayout.Space();
if (settings != null && editor != null)
{
EditorGUI.BeginDisabledGroup(true);
EditorGUILayout.ObjectField(settings, typeof(Object), false);
EditorGUI.EndDisabledGroup();
EditorGUILayout.Space();
editor.OnInspectorGUI();
}
EditorGUILayout.EndScrollView();
}
void OnInspectorUpdate()
{
this.Repaint();
}
}
}
上面這個腳本便是繼承于EditorWindow。但是有幾個地方想說明一下
AssetDatabase.FindAssets
AssetDatabase.GUIDToAssetPath
AssetDatabase.LoadAssetAtPath
上面三個方法一般是搭配出現(xiàn),首先在所有資源里面查找到你所需要的文件名,可能項目里存在一個,也可能是多個。
FindAssets一般返回一個媒介,可以通過GUIDToAssetPath將媒介轉換成文件所在路徑。前兩個方法相當于通過文件名查找到文件所在路徑。LoadAssetAtPath方法則是通過路徑加載文件??赡苡悬c繞。。。
關鍵來了
現(xiàn)在我們可以擴展文件里面所有的.asset文件,只需要不到十行的代碼,就可以把 inspector面板上顯示的信息擴展一個新的窗口顯示出來了。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using MyUtility;
public class AudioSettingsEditorWindow : ScriptableObjectBrowserEditorWindow<AudioSettingsEditorWindow>
{
protected override string FileName
{
get { return "PacManAudioSetting"; }
}
[MenuItem("Tools/PacManAudioSetting")]
static void Open()
{
OpenWindow("AudioSetting");
}
這就是效果圖,和在項目里慢慢去找到.asset文件,點擊顯示在面板上面的內容一模一樣了

好了,本次水文結束