编辑器扩展(扩展ScriptableObject文件)

在开始今天的编辑器扩展之前,先说一下unity的一大基类的,可能所有的unity程序员都熟悉MonoBehaviour 和Editor。但是unity其实还为我们准备了两个很厉害的类,它们分别是ScriptableObject和EditorWindow。

ScriptableObject

首先聊聊ScriptableObject类,它可以用于生成一个.asset文件,我称之为一个数据容器,用来储存序列化和反序列化的数据。一些简单的数据也可以不用xml或者josn储存啦。


111.png
222.png

上面的图片可以看到,我们生成了一个.asset文件,点击它可以在inspector面板上面显示相关数据。

EditorWindow

现在我们来聊聊EditorWindow,就像图片显示的情况一样,虽然我们可以点击.asset文件然后在inspector面板上面修改和查看数据,但是有一个问题就是当项目越来越大的时候每次要修改数据都要在Project里面慢慢去找文件非常麻烦。所以我们可以考虑扩展编辑器窗口。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.Linq;

namespace MyUtility
{
    /// 
    /// 显示 查找的 第一个 ScriptableObject
    /// 
    public abstract class ScriptableObjectBrowserEditorWindow : EditorWindow where T : ScriptableObjectBrowserEditorWindow
    {
        protected abstract string FileName { get; }
        Object settings = null;
        Editor editor = null;
        Vector2 scrollPos;
        public static void OpenWindow(string windowName)
        {
            T window = GetWindow(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(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
上面三个方法一般是搭配出现,首先在所有资源里面查找到你所需要的文件名,可能项目里存在一个,也可能是多个。
FindAssets一般返回一个媒介,可以通过GUIDToAssetPath将媒介转换成文件所在路径。前两个方法相当于通过文件名查找到文件所在路径。LoadAssetAtPath方法则是通过路径加载文件。可能有点绕。。。

关键来了

现在我们可以扩展文件里面所有的.asset文件,只需要不到十行的代码,就可以把 inspector面板上显示的信息扩展一个新的窗口显示出来了。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using MyUtility;

public class AudioSettingsEditorWindow : ScriptableObjectBrowserEditorWindow
{
    protected override string FileName
    {
        get { return "PacManAudioSetting"; }
    }

    [MenuItem("Tools/PacManAudioSetting")]
    static void Open()
    {
        OpenWindow("AudioSetting");
    }

这就是效果图,和在项目里慢慢去找到.asset文件,点击显示在面板上面的内容一模一样了


999.png

好了,本次水文结束

你可能感兴趣的:(编辑器扩展(扩展ScriptableObject文件))