I noticed Unity creates an "UserSettings" directory next to "ProjectSettings". This seems to be new in 2020.1. Any documentation about this?
Yeah we moved Library/EditorUserSettings.asset into this new folder. The reason being, that Library should contain only imported/cached data that can be completely reconstructed from the project. People delete their Library folders all the time, etc. But, parts of editor settings were in Library/EditorUserSettings.asset file (things like user's perforce connection settings etc.). So now it's in that new location. The folder should not be put into version control, since it's per-user things there. See "Editor: Unity projects now have "UserSettings" top-level folder, EditorUserSettings.asset moved from Library there" in release notes, and mentions of the folder in https://docs.unity3d.com/2020.1/Documentation/Manual/ExternalVersionControlSystemSupport.html docs page
Is it possible/advisable to create per-user settings (ScriptableObject asset files for example) for your own custom tools in Unity and store them in this folder?
AssetDatabase.CreateAsset doesn't allow this, unfortunately, but to me it sounds like a good idea as well.
Not officially at the moment, but hopefully in the future. In the meantime, we can still use Unity's internal API to place assets in the UserSettings folder: UnityEditorInternal.InternalEditorUtility.SaveToSerializedFileAndForget I've been doing this before Unity started using this folder name, but I assume they won't delete any files in there so it should be safe enough.
@Aras It would be very helpful if Unity would allow the "UserSettings" folder as a valid location for ScriptableObject assets with maybe some guidelines as to how plugins should store their settings there (ie: "UserSettings/CompanyName/ProductName.settings").
According to the documentation, yes the UserSettings folder should be excluded from version control: https://docs.unity3d.com/2020.1/Documentation/Manual/ExternalVersionControlSystemSupport.html
Actually, yes! I believe you can do this already, though I haven't yet delved deep into it, so apologies that I can't offer a more complete explanation: You can create custom settings under.. - Edit > Preferences > XXX (UnityEditor.SettingsScope.User) - Edit > Project Settings > XXX (UnityEditor.SettingsScope.Project) See UnityEditor.SettingsProvider for an example. It's pretty lit.
@ModLunar - The SettingsProvider is used to basically register your settings and display the UI in the Preferences and Project Settings dialogs. It does not handle the actual saving (that you must provide). And Unity does not allow you to read/write assets to the UserSettings/ or ProjectSettings/ folders which is the issue. So to use ScriptableObjects to easily add new properties and get 'free' serialization, you end up having to make additional (non standard) folders like Assets/UserSettings/ and exclude that from source control also. This is quite annoying for plugin developers to have to tell users to do an additional setup step. And it can cause issues for those developing multiplayer games and wanting to test using a junction/symbolic link to the Assets/ folder. This article describes our current solution, but it would be much cleaner if we could save to the existing folders. Considering this is such a basic feature for many developers, it would be great if Unity could standardize and simplify it.
@Ziflin Ahh I see your point now! Thanks for clarifying. I suppose they expect us to use EditorPrefs, but perhaps you want shared project settings (in Git/version control), am I right? We could do something like (just as a quick and dirty code example).. Code (CSharp): public class SavedSettings : ScriptableObject { [SerializeField] private Vector2 someSavedVector; [SerializeField] private bool someSavedBoolean; public Vector2 SomeSavedVector { get { return someSavedVector; } set { someSavedVector = value; } } public bool SomeSavedBoolean { get { return someSavedBoolean; } set { someSavedBoolean = value; } } } //Save: SavedSettings save = ScriptableObject.CreateInstance<SavedSettings>(); save.SomeSavedVector = new Vector2(-94, 106); save.SomeSavedBoolean = true; string json = EditorJsonUtility.ToJson(save, true); File.WriteAllText("UserSettings/Example Save Data.json", json); //Load: SavedSettings load = ScriptableObject.CreateInstance<SavedSettings>(); string json = File.ReadAllText("UserSettings/Example Save Data.json"); EditorJsonUtility.FromJsonOverwrite(json, load); Debug.Log(load.SomeSavedVector); Debug.Log(load.SomeSavedBoolean); Not sure how others feel about a potential solution like this though, but it works!
@ModLunar The non-editor (JsonUtility) serializer is not as advanced as the EditorJsonUtility one used for Unity Objects unfortunately, so last time we tested it, it would not work for what we need. I haven't checked to see if EditorJsonUtility supports the newer [SerializedReference] attribute, but JsonUtility seems to not support it (https://forum.unity.com/threads/unity-does-not-support-serializereference-in-jsonutility.975405/). There are a few other reasons why using a SerializedObject asset is nicer and it's certainly more consistent.
Ahh that is true, JsonUtility has "less".. I forget the details, but if you're making custom ScriptableObjects with [SerializeField] or public fields (ew), you should be fine. I'm really curious about if EditorJsonUtility supports [SerializeReference], that'd be awesome! I'm leaning towards yes, it should.. Hmm ahhhh.. like Undo support, generic property drawer/editor GUI stuff, etc.? You can make a new SerializedObject(yourScriptableObject) at any point in your code, would that help? I understand your struggle though lol. It'd be nice if something like this was built-in.