白泽图

  • 文章
    • Unity渲染
    • Unity项目开发
    • 工具
    • 数学
    • 算法
    • 网站搭建
    • 网络&操作系统
蒋程个人博客
互联网技术经验总结&分享
  1. 首页
  2. Unity项目开发
  3. 正文

Unity Editor 扩展 ProjectSetting 与 Preferences 窗口

2022-06-07 2619点热度 1人点赞 0条评论

先看一下最终效果

这是ProjectSetting窗口效果,我实际存储了TBCEditorSetting.asset这个资源的GUID,这里只是重写了GUI

数据存储在ProjectSettings/TBCFrameworkSettings.asset

这里要注意的是这个asset文件不在Assets文件夹下,所以不能使用AssetDatabase来加载,需要使用InternalEditorUtility的LoadSerializedFileAndForget与SaveToSerializedFileAndForget接口进行加载与创建/保存

另一个注意点是继承ScriptableObject的类的文件夹要与类名保存一致,和Momobehaivor脚本一样

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
using UnityEngine.UIElements;
namespace TBC.Editor
{
    class TBCProjectSettings: ScriptableObject
    {
        [System.Serializable]
        class SerializeProperty
        {
            public string Key;
            public string Value;
        }
        //serialize cache
        [SerializeField]
        List<SerializeProperty> m_Cache = new List<SerializeProperty>();
        //runtime cache
        Dictionary<string, string> m_RTCache = new Dictionary<string, string>();
        //save path
        const string s_AssetPath = "ProjectSettings/TBCFrameworkSettings.asset";


        static TBCProjectSettings s_Instance;
        static TBCProjectSettings Instance
        {
            get
            {
                if (s_Instance == null)
                {
                    var objs = InternalEditorUtility.LoadSerializedFileAndForget(s_AssetPath);
                    if (objs != null && objs.Length > 0)
                    {
                        s_Instance = objs[0] as TBCProjectSettings;
                        Debug.LogError(objs[0]);
                    }
                    if (s_Instance == null)
                    {
                        s_Instance = ScriptableObject.CreateInstance<TBCProjectSettings>();
                        s_Instance.hideFlags = HideFlags.HideAndDontSave;
                    }
                    Init();
                }
                return s_Instance;
            }
        }

        static void Init()
        {
            Instance.m_RTCache.Clear();
            foreach (var v in Instance.m_Cache)
                Instance.m_RTCache.Add(v.Key, v.Value);
        }


        internal static string GetValue(string key)
        {
            string v;
            Instance.m_RTCache.TryGetValue(key, out v);
            return v;
        }

        internal static void SetValue(string key,string value)
        {
            if (Instance.m_RTCache.ContainsKey(key))
            {
                Instance.m_RTCache[key] = value;
            }
            else
            {
                Instance.m_RTCache.Add(key, value);
                Instance.m_Cache.Add(new SerializeProperty() { Key = key, Value = value });
            }
        }

        internal static void Save()
        {
            InternalEditorUtility.SaveToSerializedFileAndForget(new Object[] { Instance }, s_AssetPath, true);
        }
    }

}

扩展ProjectSetting窗口需要用到SettingsProvider,详情参见官方文档,很详细

这里简单总结一下,SettingsProvider有两种用法,第一种是通过一个静态函数加标签创建SettingsProvider对象,然后通过里面的回调函数进行扩展

第二种是自己写一个类,继承SettingsProvider,然后通过override接口的方式进行扩展

这里我用的第一种方法,代码如下,供参考

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
using UnityEngine.UIElements;
namespace TBC.Editor
{
    internal static class TBCProjectSettingsWindow
    {
        static GUIContent m_EditorSettingLabel = new GUIContent("Scriptable TBC Editor Settings");
        static string m_EditorSettingAssetGUID = "_TBCFramework(EditorSettingAssetGUID)";
        static Object m_EditorSettingAsset;

        [SettingsProvider]
        static SettingsProvider CreateTBCFrameworkSettingsProvider()
        {
            var provider = new SettingsProvider("Project/TBC Framework", SettingsScope.Project)
            {
                guiHandler = (searchContext) =>
                {
                    EditorGUI.BeginChangeCheck();

                    EditorGUILayout.BeginVertical(GUI.skin.box);

                    EditorGUILayout.BeginVertical(EditorStyles.helpBox);
                    EditorGUILayout.LabelField(m_EditorSettingLabel);
                    var lastAsset = m_EditorSettingAsset;
                    m_EditorSettingAsset = EditorGUILayout.ObjectField(m_EditorSettingAsset, typeof(TBCEditorSetting), false);
                    if (m_EditorSettingAsset != lastAsset)
                    {
                        var path = m_EditorSettingAsset != null ? AssetDatabase.GetAssetPath(m_EditorSettingAsset) : null;
                        var guid = !string.IsNullOrEmpty(path) ? AssetDatabase.AssetPathToGUID(path) : null;
                        TBCProjectSettings.SetValue(m_EditorSettingAssetGUID, guid);
                    }

                    EditorGUILayout.EndVertical();
                    EditorGUILayout.EndVertical();


                    if (EditorGUI.EndChangeCheck())
                        TBCProjectSettings.Save();

                },


                activateHandler = (string a, VisualElement b) =>
                {
                    var scriptableGuid = TBCProjectSettings.GetValue(m_EditorSettingAssetGUID);
                    if (!string.IsNullOrEmpty(scriptableGuid))
                    {
                        var path = AssetDatabase.GUIDToAssetPath(scriptableGuid);
                        m_EditorSettingAsset = !string.IsNullOrEmpty(path) ? AssetDatabase.LoadAssetAtPath<Object>(path) : null;
                    }
                },


                keywords = new HashSet<string>(new[] { "TBC", "TBCEditorSetting" })
            };
            return provider;
        }
    }
}

如果要扩展Preferences只需要将枚举改成SettingsScope.User即可

标签: 暂无
最后更新:2022-06-09

蒋程

这个人很懒,什么都没留下

点赞
< 上一篇
下一篇 >

文章评论

您需要 登录 之后才可以评论

COPYRIGHT © 2023 白泽图. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

登录
注册|忘记密码?