在编辑器拓展过程中如果需要保存一些数据以便在下次打开后使用,如:项目的设置,编辑器拓展需要的参数等。可以通过下面几种方式实现:
EditorPrefs
首先说下EditorPrefs,它和PlayerPrefs相似,只是后者在Runtime下使用,前者在编辑器模式下使用。在EditorPrefs中存储的数据不会限制于项目。用于存储一些编辑器相关数据,由于是明文存储,所以不适合存放密码。对于一些敏感数据,可以存放到EditorUserSettings中以二进制进行加密,使用EditorUserSettings.Set / GetConfigValue
读,取。
可以使用EditorPrefs.Get/Set
保存一些基础数据类型如:int, float,bool,string。
当然通过一些方法也是可以保存其他类型的数据,下面是封装的一些方法,相信你以看就会。
枚举类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19// Get
public static T GetEnum<T>(string prefs_key, T defaultValue)
{
string val = GetString(prefs_key, defaultValue.ToString());
string[] names = System.Enum.GetNames(typeof(T));
System.Array values = System.Enum.GetValues(typeof(T));
for (int i = 0; i < names.Length; ++i)
{
if (names[i] == val)
return (T)values.GetValue(i);
}
return defaultValue;
}
// Set
public static void SetEnum(string prefs_key, System.Enum val)
{
SetString(prefs_key, val.ToString());
}泛型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39// Get
public static T Get<T>(string prefs_key, T defaultValue) where T : Object
{
if (!key_obj_list.Contains(prefs_key))
key_obj_list.Add(prefs_key);
string path = EditorPrefs.GetString(prefs_key);
if (string.IsNullOrEmpty(path)) return null;
T retVal = SUGUIEditorTool.LoadAsset<T>(path);
if (retVal == null)
{
int id;
if (int.TryParse(path, out id))
return EditorUtility.InstanceIDToObject(id) as T;
}
return retVal;
}
// Set
public static void SetObject(string prefs_key, Object obj)
{
if (!key_obj_list.Contains(prefs_key))
key_obj_list.Add(prefs_key);
if (obj == null)
{
EditorPrefs.DeleteKey(prefs_key);
}
else
{
if (obj != null)
{
string path = AssetDatabase.GetAssetPath(obj);
EditorPrefs.SetString(prefs_key, string.IsNullOrEmpty(path) ? obj.GetInstanceID().ToString() : path);
}
else EditorPrefs.DeleteKey(prefs_key);
}
}颜色
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20// Get
public static Color GetColor(string prefs_key, Color c)
{
string strVal = GetString(prefs_key, c.r + " " + c.g + " " + c.b + " " + c.a);
string[] parts = strVal.Split(' ');
if (parts.Length == 4)
{
float.TryParse(parts[0], out c.r);
float.TryParse(parts[1], out c.g);
float.TryParse(parts[2], out c.b);
float.TryParse(parts[3], out c.a);
}
return c;
}
// Set
public static void SetColor(string prefs_key, Color c)
{
SetString(prefs_key, c.r + " " + c.g + " " + c.b + " " + c.a);
}
基本上所有类型都可以通过泛型的方式进行保存。
存放位置
平台 | 位置 |
---|---|
Windows(Unity4.x) | HKEY_CURRENT_USER\Software\Unity Technologies\UnityEditor 4.x |
Windows(Unity5.x) | HKEY_CURRENT_USER\Software\Unity Technologies\UnityEditor 5.x |
MacOS X(Unity4.x) | ~/Library/Preferences/com.unity3d.UnityEditor4.x.plist |
MacOS X(Unity5.x) | ~/Library/Preferences/com.unity3d.UnityEditor5.x.plist |
注意
- 不要在OnGUI中对EditorPrefs进行保存操作,OnGUI会被多次调用,负荷高。
- 谨慎使用
EditorPrefs.ClearAll()
.
ScriptableObject
用来存放项目中共享的数据,可以当作本地数据库,可以存储大量数据。ScriptObject的用途还是挺大的,篇幅过大之后专门写一篇关于ScriptObject的各种方便开发的用法。
Json
第三种当然是Json啦。当然网上有着各种已经成熟的Json的序列化/反序列化插件了。这里就不介绍了。下面说下Unity本身自带的一个非常小型的Json序列化工具类。但是只支持简单的数据类型,不支持List
和字典
这些数据结构。下面也是做一个小拓展,完善它的一些不足。通过将列表字典转化为对象的形式再进行序列化与反序列化,实现支持List,Dictionary 类型。
代码如下:
1 | // List<T> |
用法:
1 | // List<T> -> Json ( 例 : List<Enemy> ) |