621 lines
24 KiB
C#
621 lines
24 KiB
C#
#if UNITY_2018_3_OR_NEWER
|
|
#define SETTINGS_PROVIDER_ENABLED
|
|
#endif
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using UnityEngine;
|
|
#if SETTINGS_PROVIDER_ENABLED
|
|
#if UNITY_2019_1_OR_NEWER
|
|
using UnityEngine.UIElements;
|
|
#else
|
|
using UnityEngine.Experimental.UIElements;
|
|
#endif
|
|
#endif
|
|
|
|
namespace UnityEditor.SettingsManagement
|
|
{
|
|
/// <summary>
|
|
/// A <see cref="UnityEditor.SettingsProvider"/> implementation that creates an interface from settings reflected
|
|
/// from a collection of assemblies.
|
|
/// </summary>
|
|
#if SETTINGS_PROVIDER_ENABLED
|
|
public sealed class UserSettingsProvider : SettingsProvider
|
|
#else
|
|
public sealed class UserSettingsProvider
|
|
#endif
|
|
{
|
|
/// <summary>
|
|
/// Category string constant to check whether Unity is running in developer (internal) mode.
|
|
/// </summary>
|
|
public const string developerModeCategory = "Developer Mode";
|
|
|
|
const string k_SettingsName = "UserSettingsProviderSettings";
|
|
|
|
#if SETTINGS_PROVIDER_ENABLED
|
|
const int k_LabelWidth = 240;
|
|
|
|
static int labelWidth
|
|
{
|
|
get
|
|
{
|
|
if (s_DefaultLabelWidth != null)
|
|
return (int)((float)s_DefaultLabelWidth.GetValue(null, null));
|
|
|
|
return k_LabelWidth;
|
|
}
|
|
}
|
|
|
|
static int defaultLayoutMaxWidth
|
|
{
|
|
get
|
|
{
|
|
if (s_DefaultLayoutMaxWidth != null)
|
|
return (int)((float)s_DefaultLayoutMaxWidth.GetValue(null, null));
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
#else
|
|
const int k_LabelWidth = 180;
|
|
|
|
int labelWidth
|
|
{
|
|
get { return k_LabelWidth; }
|
|
}
|
|
|
|
int defaultLayoutMaxWidth
|
|
{
|
|
get { return 0; }
|
|
}
|
|
#endif
|
|
|
|
List<string> m_Categories;
|
|
Dictionary<string, List<PrefEntry>> m_Settings;
|
|
Dictionary<string, List<MethodInfo>> m_SettingBlocks;
|
|
#if !SETTINGS_PROVIDER_ENABLED
|
|
HashSet<string> keywords = new HashSet<string>();
|
|
#endif
|
|
static readonly string[] s_SearchContext = new string[1];
|
|
EventType m_SettingsBlockKeywordsInitialized;
|
|
Assembly[] m_Assemblies;
|
|
static Settings s_Settings;
|
|
Settings m_SettingsInstance;
|
|
|
|
#if SETTINGS_PROVIDER_ENABLED
|
|
static PropertyInfo s_DefaultLabelWidth;
|
|
static PropertyInfo s_DefaultLayoutMaxWidth;
|
|
#endif
|
|
|
|
static Settings userSettingsProviderSettings
|
|
{
|
|
get
|
|
{
|
|
if (s_Settings == null)
|
|
s_Settings = new Settings(new[] { new UserSettingsRepository() });
|
|
|
|
return s_Settings;
|
|
}
|
|
}
|
|
|
|
internal static UserSetting<bool> showHiddenSettings = new UserSetting<bool>(userSettingsProviderSettings, "settings.showHidden", false, SettingsScope.User);
|
|
internal static UserSetting<bool> showUnregisteredSettings = new UserSetting<bool>(userSettingsProviderSettings, "settings.showUnregistered", false, SettingsScope.User);
|
|
internal static UserSetting<bool> listByKey = new UserSetting<bool>(userSettingsProviderSettings, "settings.listByKey", false, SettingsScope.User);
|
|
internal static UserSetting<bool> showUserSettings = new UserSetting<bool>(userSettingsProviderSettings, "settings.showUserSettings", true, SettingsScope.User);
|
|
internal static UserSetting<bool> showProjectSettings = new UserSetting<bool>(userSettingsProviderSettings, "settings.showProjectSettings", true, SettingsScope.User);
|
|
|
|
#if SETTINGS_PROVIDER_ENABLED
|
|
/// <summary>
|
|
/// Initializes and returns a new `UserSettingsProvider` instance.
|
|
/// </summary>
|
|
/// <param name="path">The settings menu path.</param>
|
|
/// <param name="settings">The Settings instance that this provider is inspecting.</param>
|
|
/// <param name="assemblies">A collection of assemblies to scan for <see cref="UserSettingAttribute"/> and <see cref="UserSettingBlockAttribute"/> attributes.</param>
|
|
/// <param name="scopes">Which scopes this provider is valid for.</param>
|
|
/// <exception cref="ArgumentNullException">Thrown if settings or assemblies is null.</exception>
|
|
public UserSettingsProvider(string path, Settings settings, Assembly[] assemblies, SettingsScope scopes = SettingsScope.User)
|
|
: base(path, scopes)
|
|
#else
|
|
/// <summary>
|
|
/// Initializes and returns a new `UserSettingsProvider` instance.
|
|
/// </summary>
|
|
/// <param name="settings">The <see cref="Settings"/> instance that this provider is inspecting.</param>
|
|
/// <param name="assemblies">A collection of assemblies to scan for <see cref="UserSettingAttribute"/> and <see cref="UserSettingBlockAttribute"/> attributes.</param>
|
|
public UserSettingsProvider(Settings settings, Assembly[] assemblies)
|
|
#endif
|
|
{
|
|
if (settings == null)
|
|
throw new ArgumentNullException("settings");
|
|
|
|
if (assemblies == null)
|
|
throw new ArgumentNullException("assemblies");
|
|
|
|
m_SettingsInstance = settings;
|
|
m_Assemblies = assemblies;
|
|
|
|
#if !SETTINGS_PROVIDER_ENABLED
|
|
SearchForUserSettingAttributes();
|
|
#endif
|
|
}
|
|
|
|
#if SETTINGS_PROVIDER_ENABLED
|
|
/// <summary>
|
|
/// Invoked by the <see cref="UnityEditor.SettingsProvider"/> when activated in the Editor.
|
|
/// </summary>
|
|
/// <param name="searchContext">
|
|
/// Search context in the search box on the
|
|
/// [Settings](https://docs.unity3d.com/Manual/comp-ManagerGroup.html) window.
|
|
/// </param>
|
|
/// <param name="rootElement">
|
|
/// Root of the UIElements tree. If you add to this root, the SettingsProvider uses
|
|
/// [UIElements](https://docs.unity3d.com/ScriptReference/UnityEngine.UIElementsModule.html)
|
|
/// instead of calling <see cref="OnGUI"/> to build the UI.
|
|
/// See <see cref="UnityEditor.SettingsProvider.OnActivate"/> for details.
|
|
/// </param>
|
|
public override void OnActivate(string searchContext, VisualElement rootElement)
|
|
{
|
|
base.OnActivate(searchContext, rootElement);
|
|
|
|
SearchForUserSettingAttributes();
|
|
|
|
var window = GetType().GetProperty("settingsWindow", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
|
|
if (window != null)
|
|
{
|
|
s_DefaultLabelWidth = window.PropertyType.GetProperty("s_DefaultLabelWidth", BindingFlags.Public | BindingFlags.Static);
|
|
s_DefaultLayoutMaxWidth = window.PropertyType.GetProperty("s_DefaultLayoutMaxWidth", BindingFlags.Public | BindingFlags.Static);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
struct PrefEntry
|
|
{
|
|
GUIContent m_Content;
|
|
IUserSetting m_Pref;
|
|
|
|
public GUIContent content
|
|
{
|
|
get { return m_Content; }
|
|
}
|
|
|
|
public IUserSetting pref
|
|
{
|
|
get { return m_Pref; }
|
|
}
|
|
|
|
public PrefEntry(GUIContent content, IUserSetting pref)
|
|
{
|
|
m_Content = content;
|
|
m_Pref = pref;
|
|
}
|
|
}
|
|
|
|
void SearchForUserSettingAttributes()
|
|
{
|
|
var isDeveloperMode = EditorPrefs.GetBool("DeveloperMode", false);
|
|
var keywordsHash = new HashSet<string>();
|
|
|
|
if (m_Settings != null)
|
|
m_Settings.Clear();
|
|
else
|
|
m_Settings = new Dictionary<string, List<PrefEntry>>();
|
|
|
|
if (m_SettingBlocks != null)
|
|
m_SettingBlocks.Clear();
|
|
else
|
|
m_SettingBlocks = new Dictionary<string, List<MethodInfo>>();
|
|
|
|
var types = m_Assemblies.SelectMany(x => x.GetTypes());
|
|
|
|
// collect instance fields/methods too, but only so we can throw a warning that they're invalid.
|
|
var fields = types.SelectMany(x =>
|
|
x.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)
|
|
.Where(prop => Attribute.IsDefined(prop, typeof(UserSettingAttribute))));
|
|
|
|
var methods = types.SelectMany(x => x.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
|
|
.Where(y => Attribute.IsDefined(y, typeof(UserSettingBlockAttribute))));
|
|
|
|
foreach (var field in fields)
|
|
{
|
|
if (!field.IsStatic)
|
|
{
|
|
Debug.LogWarning("Cannot create setting entries for instance fields. Skipping \"" + field.Name + "\".");
|
|
continue;
|
|
}
|
|
|
|
var attrib = (UserSettingAttribute)Attribute.GetCustomAttribute(field, typeof(UserSettingAttribute));
|
|
|
|
if (!attrib.visibleInSettingsProvider)
|
|
continue;
|
|
|
|
var pref = (IUserSetting)field.GetValue(null);
|
|
|
|
if (pref == null)
|
|
{
|
|
Debug.LogWarning("[UserSettingAttribute] is only valid for types implementing the IUserSetting interface. Skipping \"" + field.Name + "\"");
|
|
continue;
|
|
}
|
|
|
|
var category = string.IsNullOrEmpty(attrib.category) ? "Uncategorized" : attrib.category;
|
|
var content = listByKey ? new GUIContent(pref.key) : attrib.title;
|
|
|
|
if (developerModeCategory.Equals(category) && !isDeveloperMode)
|
|
continue;
|
|
|
|
List<PrefEntry> settings;
|
|
|
|
if (m_Settings.TryGetValue(category, out settings))
|
|
settings.Add(new PrefEntry(content, pref));
|
|
else
|
|
m_Settings.Add(category, new List<PrefEntry>() { new PrefEntry(content, pref) });
|
|
}
|
|
|
|
foreach (var method in methods)
|
|
{
|
|
var attrib = (UserSettingBlockAttribute)Attribute.GetCustomAttribute(method, typeof(UserSettingBlockAttribute));
|
|
var category = string.IsNullOrEmpty(attrib.category) ? "Uncategorized" : attrib.category;
|
|
|
|
if (developerModeCategory.Equals(category) && !isDeveloperMode)
|
|
continue;
|
|
|
|
List<MethodInfo> blocks;
|
|
|
|
var parameters = method.GetParameters();
|
|
|
|
if (!method.IsStatic || parameters.Length < 1 || parameters[0].ParameterType != typeof(string))
|
|
{
|
|
Debug.LogWarning("[UserSettingBlockAttribute] is only valid for static functions with a single string parameter. Ex, `static void MySettings(string searchContext)`. Skipping \"" + method.Name + "\"");
|
|
continue;
|
|
}
|
|
|
|
if (m_SettingBlocks.TryGetValue(category, out blocks))
|
|
blocks.Add(method);
|
|
else
|
|
m_SettingBlocks.Add(category, new List<MethodInfo>() { method });
|
|
}
|
|
|
|
if (showHiddenSettings)
|
|
{
|
|
var unlisted = new List<PrefEntry>();
|
|
m_Settings.Add("Unlisted", unlisted);
|
|
foreach (var pref in UserSettings.FindUserSettings(m_Assemblies, SettingVisibility.Unlisted | SettingVisibility.Hidden))
|
|
unlisted.Add(new PrefEntry(new GUIContent(pref.key), pref));
|
|
}
|
|
|
|
if (showUnregisteredSettings)
|
|
{
|
|
var unregistered = new List<PrefEntry>();
|
|
m_Settings.Add("Unregistered", unregistered);
|
|
foreach (var pref in UserSettings.FindUserSettings(m_Assemblies, SettingVisibility.Unregistered))
|
|
unregistered.Add(new PrefEntry(new GUIContent(pref.key), pref));
|
|
}
|
|
|
|
foreach (var cat in m_Settings)
|
|
{
|
|
foreach (var entry in cat.Value)
|
|
{
|
|
var content = entry.content;
|
|
|
|
if (content != null && !string.IsNullOrEmpty(content.text))
|
|
{
|
|
foreach (var word in content.text.Split(' '))
|
|
keywordsHash.Add(word);
|
|
}
|
|
}
|
|
}
|
|
|
|
keywords = keywordsHash;
|
|
m_Categories = m_Settings.Keys.Union(m_SettingBlocks.Keys).ToList();
|
|
m_Categories.Sort();
|
|
}
|
|
|
|
#if SETTINGS_PROVIDER_ENABLED
|
|
/// <summary>
|
|
/// Invoked by the SettingsProvider container when drawing the UI header.
|
|
/// </summary>
|
|
public override void OnTitleBarGUI()
|
|
{
|
|
if (GUILayout.Button(GUIContent.none, SettingsGUIStyles.settingsGizmo))
|
|
DoContextMenu();
|
|
}
|
|
#endif
|
|
|
|
void InitSettingsBlockKeywords()
|
|
{
|
|
// Have to let the blocks run twice - one for Layout, one for Repaint.
|
|
if (m_SettingsBlockKeywordsInitialized == EventType.Repaint)
|
|
return;
|
|
|
|
m_SettingsBlockKeywordsInitialized = Event.current.type;
|
|
|
|
// Allows SettingsGUILayout.SettingsField to populate keywords
|
|
SettingsGUILayout.s_Keywords = new HashSet<string>(keywords);
|
|
|
|
// Set a dummy value so that GUI blocks with conditional foldouts will behave as though searching.
|
|
s_SearchContext[0] = "Search";
|
|
|
|
foreach (var category in m_SettingBlocks)
|
|
{
|
|
foreach (var block in category.Value)
|
|
block.Invoke(null, s_SearchContext);
|
|
}
|
|
|
|
keywords = SettingsGUILayout.s_Keywords;
|
|
SettingsGUILayout.s_Keywords = null;
|
|
s_SearchContext[0] = "";
|
|
}
|
|
|
|
void DoContextMenu()
|
|
{
|
|
var menu = new GenericMenu();
|
|
|
|
menu.AddItem(new GUIContent("Reset All"), false, () =>
|
|
{
|
|
if (!UnityEditor.EditorUtility.DisplayDialog("Reset All Settings", "Reset all settings? This is not undo-able.", "Reset", "Cancel"))
|
|
return;
|
|
|
|
// Do not reset SettingVisibility.Unregistered
|
|
foreach (var pref in UserSettings.FindUserSettings(m_Assemblies, SettingVisibility.Visible | SettingVisibility.Hidden | SettingVisibility.Unlisted))
|
|
pref.Reset();
|
|
|
|
m_SettingsInstance.Save();
|
|
});
|
|
|
|
if (EditorPrefs.GetBool("DeveloperMode", false))
|
|
{
|
|
menu.AddSeparator("");
|
|
|
|
menu.AddItem(new GUIContent("Developer/List Settings By Key"), listByKey, () =>
|
|
{
|
|
listByKey.SetValue(!listByKey, true);
|
|
SearchForUserSettingAttributes();
|
|
});
|
|
|
|
menu.AddSeparator("Developer/");
|
|
|
|
menu.AddItem(new GUIContent("Developer/Show User Settings"), showUserSettings, () =>
|
|
{
|
|
showUserSettings.SetValue(!showUserSettings, true);
|
|
SearchForUserSettingAttributes();
|
|
});
|
|
|
|
menu.AddItem(new GUIContent("Developer/Show Project Settings"), showProjectSettings, () =>
|
|
{
|
|
showProjectSettings.SetValue(!showProjectSettings, true);
|
|
SearchForUserSettingAttributes();
|
|
});
|
|
|
|
menu.AddSeparator("Developer/");
|
|
|
|
menu.AddItem(new GUIContent("Developer/Show Unlisted Settings"), showHiddenSettings, () =>
|
|
{
|
|
showHiddenSettings.SetValue(!showHiddenSettings, true);
|
|
SearchForUserSettingAttributes();
|
|
});
|
|
|
|
menu.AddItem(new GUIContent("Developer/Show Unregistered Settings"), showUnregisteredSettings, () =>
|
|
{
|
|
showUnregisteredSettings.SetValue(!showUnregisteredSettings, true);
|
|
SearchForUserSettingAttributes();
|
|
});
|
|
|
|
menu.AddSeparator("Developer/");
|
|
|
|
menu.AddItem(new GUIContent("Developer/Open Project Settings File"), false, () =>
|
|
{
|
|
var project = m_SettingsInstance.GetRepository(SettingsScope.Project);
|
|
|
|
if (project != null)
|
|
{
|
|
var path = Path.GetFullPath(project.path);
|
|
System.Diagnostics.Process.Start(path);
|
|
}
|
|
});
|
|
|
|
menu.AddItem(new GUIContent("Developer/Print All Settings"), false, () =>
|
|
{
|
|
Debug.Log(UserSettings.GetSettingsString(m_Assemblies));
|
|
});
|
|
|
|
#if UNITY_2019_1_OR_NEWER
|
|
menu.AddSeparator("Developer/");
|
|
#if UNITY_2019_3_OR_NEWER
|
|
menu.AddItem(new GUIContent("Developer/Recompile Scripts"), false, EditorUtility.RequestScriptReload);
|
|
#else
|
|
menu.AddItem(new GUIContent("Developer/Recompile Scripts"), false, UnityEditorInternal.InternalEditorUtility.RequestScriptReload);
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
menu.ShowAsContext();
|
|
}
|
|
|
|
#if SETTINGS_PROVIDER_ENABLED
|
|
/// <summary>
|
|
/// Called when the Settings window opens in the Editor.
|
|
/// </summary>
|
|
/// <param name="searchContext">
|
|
/// Search context in the search box on the
|
|
/// [Settings](https://docs.unity3d.com/Manual/comp-ManagerGroup.html) window.
|
|
/// </param>
|
|
/// <seealso cref="UnityEditor.SettingsProvider.OnGUI"/>
|
|
public override void OnGUI(string searchContext)
|
|
#else
|
|
/// <summary>
|
|
/// Called when the Settings window opens in the Editor.
|
|
/// </summary>
|
|
/// <param name="searchContext">
|
|
/// Search context in the search box on the
|
|
/// [Settings](https://docs.unity3d.com/Manual/comp-ManagerGroup.html) window.
|
|
/// </param>
|
|
/// <seealso cref="UnityEditor.SettingsProvider.OnGUI"/>
|
|
public void OnGUI(string searchContext)
|
|
#endif
|
|
{
|
|
#if !SETTINGS_PROVIDER_ENABLED
|
|
var evt = Event.current;
|
|
if (evt.type == EventType.ContextClick)
|
|
DoContextMenu();
|
|
#endif
|
|
InitSettingsBlockKeywords();
|
|
|
|
EditorGUIUtility.labelWidth = labelWidth;
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
|
|
var maxWidth = defaultLayoutMaxWidth;
|
|
|
|
if (maxWidth != 0)
|
|
GUILayout.BeginVertical(SettingsGUIStyles.settingsArea, GUILayout.MaxWidth(maxWidth));
|
|
else
|
|
GUILayout.BeginVertical(SettingsGUIStyles.settingsArea);
|
|
|
|
var hasSearchContext = !string.IsNullOrEmpty(searchContext);
|
|
s_SearchContext[0] = searchContext;
|
|
if (hasSearchContext)
|
|
{
|
|
// todo - Improve search comparison
|
|
var searchKeywords = searchContext.Split(' ');
|
|
|
|
foreach (var settingField in m_Settings)
|
|
{
|
|
foreach (var setting in settingField.Value)
|
|
{
|
|
if (searchKeywords.Any(x => !string.IsNullOrEmpty(x) && setting.content.text.IndexOf(x, StringComparison.InvariantCultureIgnoreCase) > -1))
|
|
DoPreferenceField(setting.content, setting.pref);
|
|
}
|
|
}
|
|
|
|
foreach (var settingsBlock in m_SettingBlocks)
|
|
{
|
|
foreach (var block in settingsBlock.Value)
|
|
{
|
|
block.Invoke(null, s_SearchContext);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
foreach (var key in m_Categories)
|
|
{
|
|
GUILayout.Label(key, EditorStyles.boldLabel);
|
|
|
|
List<PrefEntry> settings;
|
|
|
|
if (m_Settings.TryGetValue(key, out settings))
|
|
foreach (var setting in settings)
|
|
DoPreferenceField(setting.content, setting.pref);
|
|
|
|
List<MethodInfo> blocks;
|
|
|
|
if (m_SettingBlocks.TryGetValue(key, out blocks))
|
|
foreach (var block in blocks)
|
|
block.Invoke(null, s_SearchContext);
|
|
|
|
GUILayout.Space(8);
|
|
}
|
|
}
|
|
|
|
EditorGUIUtility.labelWidth = 0;
|
|
|
|
GUILayout.EndVertical();
|
|
|
|
if (EditorGUI.EndChangeCheck())
|
|
{
|
|
m_SettingsInstance.Save();
|
|
}
|
|
}
|
|
|
|
void DoPreferenceField(GUIContent title, IUserSetting pref)
|
|
{
|
|
if (EditorPrefs.GetBool("DeveloperMode", false))
|
|
{
|
|
if (pref.scope == SettingsScope.Project && !showProjectSettings)
|
|
return;
|
|
if (pref.scope == SettingsScope.User && !showUserSettings)
|
|
return;
|
|
}
|
|
|
|
if (pref is UserSetting<float>)
|
|
{
|
|
var cast = (UserSetting<float>)pref;
|
|
cast.value = EditorGUILayout.FloatField(title, cast.value);
|
|
}
|
|
else if (pref is UserSetting<int>)
|
|
{
|
|
var cast = (UserSetting<int>)pref;
|
|
cast.value = EditorGUILayout.IntField(title, cast.value);
|
|
}
|
|
else if (pref is UserSetting<bool>)
|
|
{
|
|
var cast = (UserSetting<bool>)pref;
|
|
cast.value = EditorGUILayout.Toggle(title, cast.value);
|
|
}
|
|
else if (pref is UserSetting<string>)
|
|
{
|
|
var cast = (UserSetting<string>)pref;
|
|
cast.value = EditorGUILayout.TextField(title, cast.value);
|
|
}
|
|
else if (pref is UserSetting<Color>)
|
|
{
|
|
var cast = (UserSetting<Color>)pref;
|
|
cast.value = EditorGUILayout.ColorField(title, cast.value);
|
|
}
|
|
#if UNITY_2018_3_OR_NEWER
|
|
else if (pref is UserSetting<Gradient>)
|
|
{
|
|
var cast = (UserSetting<Gradient>)pref;
|
|
cast.value = EditorGUILayout.GradientField(title, cast.value);
|
|
}
|
|
#endif
|
|
else if (pref is UserSetting<Vector2>)
|
|
{
|
|
var cast = (UserSetting<Vector2>)pref;
|
|
cast.value = EditorGUILayout.Vector2Field(title, cast.value);
|
|
}
|
|
else if (pref is UserSetting<Vector3>)
|
|
{
|
|
var cast = (UserSetting<Vector3>)pref;
|
|
cast.value = EditorGUILayout.Vector3Field(title, cast.value);
|
|
}
|
|
else if (pref is UserSetting<Vector4>)
|
|
{
|
|
var cast = (UserSetting<Vector4>)pref;
|
|
cast.value = EditorGUILayout.Vector4Field(title, cast.value);
|
|
}
|
|
else if (typeof(Enum).IsAssignableFrom(pref.type))
|
|
{
|
|
Enum val = (Enum)pref.GetValue();
|
|
EditorGUI.BeginChangeCheck();
|
|
if (Attribute.IsDefined(pref.type, typeof(FlagsAttribute)))
|
|
val = EditorGUILayout.EnumFlagsField(title, val);
|
|
else
|
|
val = EditorGUILayout.EnumPopup(title, val);
|
|
if (EditorGUI.EndChangeCheck())
|
|
pref.SetValue(val);
|
|
}
|
|
else if (typeof(UnityEngine.Object).IsAssignableFrom(pref.type))
|
|
{
|
|
var obj = (UnityEngine.Object)pref.GetValue();
|
|
EditorGUI.BeginChangeCheck();
|
|
obj = EditorGUILayout.ObjectField(title, obj, pref.type, false);
|
|
if (EditorGUI.EndChangeCheck())
|
|
pref.SetValue(obj);
|
|
}
|
|
else
|
|
{
|
|
GUILayout.BeginHorizontal();
|
|
GUILayout.Label(title, GUILayout.Width(EditorGUIUtility.labelWidth - EditorStyles.label.margin.right * 2));
|
|
var obj = pref.GetValue();
|
|
GUILayout.Label(obj == null ? "null" : pref.GetValue().ToString());
|
|
GUILayout.EndHorizontal();
|
|
}
|
|
|
|
SettingsGUILayout.DoResetContextMenuForLastRect(pref);
|
|
}
|
|
}
|
|
}
|