編輯器擴展(擴展ScriptableObject文件)

在開始今天的編輯器擴展之前,先說一下unity的一大基類的,可能所有的unity程序員都熟悉MonoBehaviour 和Editor。但是unity其實還為我們準備了兩個很厲害的類,它們分別是ScriptableObject和EditorWindow。

ScriptableObject

首先聊聊ScriptableObject類,它可以用于生成一個.asset文件,我稱之為一個數(shù)據容器,用來儲存序列化和反序列化的數(shù)據。一些簡單的數(shù)據也可以不用xml或者josn儲存啦。


111.png
222.png

上面的圖片可以看到,我們生成了一個.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文件,點擊顯示在面板上面的內容一模一樣了


999.png

好了,本次水文結束

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容