EditorPrefs stores preferences that are shared between projects. To store preferences specific to the current project, something like adding the project “ID” to the preference key could work, but what should I use as ID?
4 Answers
4Your editor code can create an asset file in the project structure(better in the same folder of editor script file) as a data storage.
You can store a generated ID in that asset.
If the editor code can’t find this asset in project, then it’s a new project and it’s time to create the file.
If the asset is already in the project, Editor code uses the ID in it to distinguish per project settings in EditorPrefs.
See this post for how to create an asset file
Clever trick, but if people copy the script assets to a different project, kaboom, there it goes the whole plan. If I can't find a robust way I'll use this idea, though.
– moreyesYou can store the project path in the same asset. When you detect a path change, In the editor window, you can notify the user that he may be using the settings from a different project and ask him if he want to create a settings profile for that project. don't do this warning in a popup window. Put a Yellow or green text and a button at the bottom of your editor window.
– XtroThat sounds good. Actually, no need to notify the user, just create a new ID and save it with a new path, and copy the old settings to the new ID.
– moreyesIf you create a new ID automatically on detection of path change. it will have the same problem you've mentioned under the ATMEthan's comment. Notifying the user looks like the best way to me.
– XtroIf you move the project to a different path, you're gonna create a new ID for it. But actually it's the same project which has been moved and it's gonna lose the per project settings. Am I wrong ?
– XtroJust for the record, I ended creating my own ProjectPrefs serializer/deserializer. It is a class that reads and stores a preferences file in the Assets folder. The API mimics EditorPrefs, but preferences are related to the current project:
// Getting values.
string foo = ProjectPrefs.GetString("foo");
string bar = ProjectPrefs.GetString("bar", "bar");
int baz = ProjectPrefs.GetInt("baz", 100);
// ...
// Setting values.
ProjectPrefs.SetString("foo", "foo");
ProjectPrefs.SetString("bar", "bar");
ProjectPrefs.SetInt("baz", 100);
/// ...
ProjectPrefs.Save();
The only difference from EditorPrefs is that it has a method Save() that must be called manually after values are set, just so that the values are not serialized every time a new one is added.
Just to help to others like me that came here looking for a solution.
Here you’ve got an asset that can do what @moreyes said.
This library stores preferences in your project folder instead of the system preferences.
For quick and dirty implementation. Could done it like this:
public static class EditorProjectPrefs
{
static string MakeProjectSpecificEditorPrefKey( string k )
{
int projectPathHash = Application.dataPath.GetHashCode( );
return $"{projectPathHash:X}.{k}";
}
public static void SetInt( string k, int v ) => EditorPrefs.SetInt( MakeProjectSpecificEditorPrefKey( k ), v );
public static int GetInt( string k ) => EditorPrefs.GetInt( MakeProjectSpecificEditorPrefKey( k ) );
public static void SetString( string k, string v ) => EditorPrefs.SetString( MakeProjectSpecificEditorPrefKey( k ), v );
public static string GetString( string k ) => EditorPrefs.GetString( MakeProjectSpecificEditorPrefKey( k ) );
}
Explain: Application.dataPath returns path to “Assets” folder of your project, whether calling it by game script or editor script. So turn it into hash (int) then print it with “X” format (uppercase hexadecimal) and prepend it with original key. BOOM. done.
Could the key be the bundle id? That's something that is unique to each individual project.
– ATMEthanThis is for an editor extension, so I think it should be specific to the opened project... maybe use its absolute path, but this could change so it doesn't look like a good candidate for ID.
– moreyes