Unity Editor 扩展 ProjectSetting 与 Preferences 窗口

Unity Editor 扩展 ProjectSetting 与 Preferences 窗口

先看一下最终效果

这是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 m_Cache = new List();

//runtime cache

Dictionary m_RTCache = new Dictionary();

//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();

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(path) : null;

}

},

keywords = new HashSet(new[] { "TBC", "TBCEditorSetting" })

};

return provider;

}

}

}

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

相关推荐

合作伙伴