It would be great if someone from Unity could please comment on any plans for improvements to User & Project Settings standardization. Perhaps I’ve missed something, but here’s my take on types of settings that we need (and issues with the current “solutions”):
User Settings (Editor Only)
These are per-user settings that are only needed in the editor.
Should ideally be ScriptableObject-derived and stored in /UserSettings/
Storing them in /Assets is not desired for those of us working on multiplayer games that need to use symbolic links to /Assets to quickly test multiplayer games. This would also require users adding another folder to be ignored by version control.
Currently AssetDatabase.CreateAsset()fails to create/load in /UserSettings/.
EditorPrefs - Only useful for minor settings and suffers the same problem for multiplayer testing. Requires more work to use than a ScriptableObjects.
Json - Serialization is not as advanced as ScriptableObjects without additional libraries. Another format should not be required.
Ideally Unity would provide a UserSettings.Get<T>() accessor to return the settings instance.
Project Settings (Editor and Runtime)
Project-wide settings that can be accessed by editor plug-ins or at runtime.
Again, would ideally be ScriptableObject-derived and stored in /ProjectSettings/. Editor-only settings could be stored in an Editor/ sub-directory and excluded from builds.
Ideally Unity would provide a ProjectSettings.Get<T>() accessor to return the settings instance. Runtime settings should be loaded when the player starts and be accessible at runtime.
Currently, to have runtime-accessible project-wide settings requires placing them in a Resources/ sub-directory and calling Resources.Load() to load them.
SettingsProvider Improvements
Add a [Settings] attribute or base classes so that the editor’s settings UI can do everything without us needing to write a custom SettingsProvider unless custom UI is required.
This means that exposing new settings would only require writing a very minimal class with just the settings as fields.
At the very least provide a static SettingsProvider.DrawDefaultInspector(so) call similar to the one in the Editor class to avoid having to write individual PropertyField() calls.
I’m sure I’ve missed a few things, but it’s currently a bit frustrating that there still isn’t a simple/standard way to implement settings for these use cases.
+1 for this. I just discovered that AssetDatabase.CreateAsset() denies creating a scriptable object instance inside UserSettings. This is unfortunate, and requires us to to add yet another folder to .gitignore, as mentioned by the original creator of this thread.
You really should use ScriptableSingleton if you want to have editor settings-like things. You even have the choice to store them automatically inside the Assets or outside per user.
@ what is the benefit of using a ScriptableSingleton over a regular ScriptableObject with persistence? It seems it take over the persistence part, but that’s about it, right? But in any case, I assume scriptable singletons also don’t allow writing to UserSettings, or do they?
Yea and Settings Per User Per Project pls.
So I can write things like a favorite explorer for GameObjects in a scene, which is obviously only relevant inside ONE specific project, but also only relevant for one user.
[FilePath("UserSettings/MyTestSettings.asset", FilePathAttribute.Location.ProjectFolder)]
internal class MyTestSettings : ScriptableSingleton<MyTestSettings>
{
[SerializeField] private int _changeCount;
[SerializeField] private string _someValue;
public string SomeValue
{
get => _someValue;
set
{
_someValue = value;
_changeCount++;
Save(true);
}
}
public int ChangeCount => _changeCount;
[MenuItem("Test/Poke My Test Settings")]
public static void Poker()
{
MyTestSettings.instance.SomeValue = $"Hello world..! I've been poked {MyTestSettings.instance.ChangeCount}x times!";
}
}
Creates an .asset in UserSettings, works as expected. Use Test -> Poke My Test Settings option to (generate) and modify the test settings asset. Navigate the UserSettings folder to see it changing.
@Prodigga while your solution works, it doesn’t appear to completely satisfy the original requirements laid out by @Ziflin . Unless I’m misunderstanding, this part says: Project-wide settings that can be accessed by editor plug-ins or at runtime..
Currently ScriptableSingleton<> is only usable under the UnityEditor namespace, as such it will fail to compile if we included it in the build, so therefore it’s use during runtime isn’t viable.
@Mako-Infused Yeah, this was the same issue that I’ve run into regarding it only being useful in the editor. Unless I’ve missed an update, there’s still no way for us to save ScriptableObjects to ProjectSettings/ for use at runtime, though clearly Unity does with several of their project settings such as the ones for Physics and Time.
Also, with the code from @Prodigga above which uses a property set/get, you cannot easily expose the settings to a SettingsProvider without making custom settings UI.
When trying to use a ScriptableSingleton with a SettingsProvider (or just making a custom GUI), the fields are not modifiable (greyed out) in the preferences/inspector GUI. Does anyone know how to fix this?