Last active
November 24, 2023 13:29
-
-
Save Doppelkeks/b1c1c081a11923e2ef760c9cd770dc9a to your computer and use it in GitHub Desktop.
Unity provides the SettingsProvider API to create custom project settings. Additionally, there exists the ScriptableSingleton class to create a scriptable objects that can be statically referenced and kept outside the assets folder. This combines both APIs, to create custom project settings in the editor without the hassle.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[FilePath("ProjectSettings/" + nameof(ExampleProjectSettings) + ".asset", FilePathAttribute.Location.ProjectFolder)] | |
public class ExampleProjectSettings : SimpleSettings<ExampleProjectSettings> { | |
/// <summary> | |
/// the display path in the project settings window | |
/// </summary> | |
private const string WINDOW_PATH = "Tools/" + nameof(ExampleProjectSettings); | |
public bool exampleSettingBool; | |
/// <summary> | |
/// Register the settings provider for the project settings | |
/// </summary> | |
/// <returns></returns> | |
[SettingsProvider] | |
public static SettingsProvider RegisterInProjectSettings() { | |
return new SimpleSettingsProvider<ExampleProjectSettings>(WINDOW_PATH); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEditor; | |
using UnityEngine; | |
public class SimpleProjectSettings<T> : ScriptableSingleton<T> where T : SimpleSettings<T> { | |
public void OnEnable() { | |
hideFlags &= ~HideFlags.NotEditable; | |
} | |
public void Save() { | |
base.Save(true); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEditor; | |
using UnityEditor.UIElements; | |
using UnityEngine; | |
using UnityEngine.UIElements; | |
public class SimpleSettingsProvider<T> : SettingsProvider where T : SimpleSettings<T> { | |
private SerializedObject serializedData; | |
private string headline; | |
public SimpleSettingsProvider(string path, string headline=null, string[] keywords = null) : base(path, SettingsScope.Project) { | |
this.headline = headline ?? typeof(T).Name; | |
this.keywords = keywords ?? (new string[] { typeof(T).Name }); | |
} | |
public override void OnActivate(string searchContext, VisualElement rootElement) { | |
serializedData = new SerializedObject(SimpleSettings<T>.instance); | |
CreateHeaderAndAddStyles(rootElement); | |
// Create a scroll view with a inspector inside | |
ScrollView scrollView = new ScrollView(ScrollViewMode.Vertical); | |
InspectorElement inspectorRoot = new InspectorElement(); | |
scrollView.Add(inspectorRoot); | |
rootElement.Add(scrollView); | |
// Bind a callback to save changes | |
// Binding it to the root is enough | |
rootElement.RegisterCallback<SerializedPropertyChangeEvent>(ValueChanged); | |
// Populate the properties | |
inspectorRoot.Bind(serializedData); | |
} | |
protected virtual void CreateHeaderAndAddStyles(VisualElement root) { | |
// create and add label | |
Label title = new Label(headline); | |
title.style.fontSize = 20; | |
title.style.unityFontStyleAndWeight = FontStyle.Bold; | |
title.style.marginBottom = 10; | |
title.AddToClassList(nameof(title)); | |
title.style.paddingTop = title.style.paddingRight = 2; | |
title.style.paddingBottom = 0; | |
title.style.paddingLeft = 5; | |
root.Add(title); | |
} | |
protected virtual void ValueChanged(SerializedPropertyChangeEvent evt) { | |
(serializedData.targetObject as T).Save(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks to the Unity Essential Success team for cooking up the classes this solution extends upon.
Nonetheless, please be aware that this code has not yet been battletested.