Unity Webgl小游戏存取数据的解决方案

在Unity中,如果我们要存储数据,通常会使用以下几种方法:

1.Unity官方提供的PlayerPrefs

2.Unity官方提供的ScriptableObject

3.使用Json,XML,CSV等文件保存

4.使用数据库存储

 

而在Webgl手机小游戏中,通常会以PlayerPrefs进行保存,因为PlayerPrefs是一个极其轻量级的存储方式

可以用于存储一些小游戏的数据(只能存储int,float,string三种类型)

它主要的方法有以下这些:

 1 // 保存玩家的分数
 2 PlayerPrefs.SetInt("PlayerScore", 100);
 3 // 获取玩家的分数,默认值为0
 4 int playerScore = PlayerPrefs.GetInt("PlayerScore", 0);
 5 // 保存音量设置
 6 PlayerPrefs.SetFloat("Volume", 0.5f);
 7 // 获取音量,默认值为1.0
 8 float volume = PlayerPrefs.GetFloat("Volume", 1.0f);
 9 // 保存玩家的名字
10 PlayerPrefs.SetString("PlayerName", "qingyuan");
11 // 获取玩家名字,默认值为"Unknown"
12 string playerName = PlayerPrefs.GetString("PlayerName", "Unknown");
13 // 删除保存的玩家分数
14 PlayerPrefs.DeleteKey("PlayerScore");
15 // 删除所有存储的数据
16 PlayerPrefs.DeleteAll();
17 // 检查是否存在“PlayerScore”
18 if (PlayerPrefs.HasKey("PlayerScore"))
19 {
20     // 存在玩家分数
21     int score = PlayerPrefs.GetInt("PlayerScore");
22 }
23 // 手动保存数据
24 PlayerPrefs.Save();

其中有一些需要注意的地方,这三组get,set方法,它们的key均为string类型,而值的类型则与方法名对应。

关于手动保存数据这个函数,通常,PlayerPrefs 在调用 Set 方法时会自动保存数据,但在某些情况下(如游戏退出前),你可以调用 PlayerPrefs.Save() 来确保数据保存。

这种保存方法的优点是轻量级,存取方便,缺点在于它的数据及其容易被修改,比如在Winodws系统下,它会将数据存储在注册表中,你可以轻而易举的查看或者修改它。

值得注意的是,如果小游戏是类似微信小程序的那种,则不能使用以下的方式进行存储,因为下面的这种方式涉及文件读写。

1 private void SaveLevelData()
2 {
3     //apk的储存方法
4     FileStream fileStream = File.Create(UserGameDataFilePath);
5     Debug.Log("当前用户数据保存路径:" + UserGameDataFilePath);
6     new BinaryFormatter().Serialize(fileStream, MultiplayerHandler.instance.UserGameData);
7     Debug.Log("UserGameData:" + MultiplayerHandler.instance.UserGameData);
8     fileStream.Close();
9 }

下面我以一个实际项目的说说类似Webgl小游戏如何存取数据:

首先,我有一个LevelData类:

 1 public class LevelData
 2 {
 3     public string levelName;
 4 
 5     public bool isCompleted;
 6 
 7     public int score;
 8 
 9     public float completionTime;
10 }

由于关卡很多,所以我还声明了一个List<LevelData> UserGameData队列:

public List<LevelData> UserGameData;

可以看出,我的LevelData类中有好几个要存储的变量,如果单纯用上述的PlayerPrefs进行get,set,那代码量就显得很多,而且读取也不好进行读取

所以我的想法是:先将整个List序列化为Json,然后使用PlayerPrefs.SetString()保存(毕竟int,float能存的,String都可以),读取的时候再使用PlayerPrefs.GetString()的读取,然后反序列化为List对象。

以下是实现的代码:

 1 public static void SaveUserData(string key, object data)
 2 {
 3     //将数据转换为json,并以UserData这个键名保存
 4     var json = JsonConvert.SerializeObject(data, Formatting.Indented);
 5     Gtools.SetString_SaveChange(key, json);
 6 }
 7 
 8 
 9 public static void LoadFromPlayerPrefs()
10 {
11     var json = Gtools.GetString_SaveChange("UserData");
12     List<LevelData> dataList = JsonConvert.DeserializeObject<List<LevelData>>(json);
13     if (dataList != null && dataList.Count > 0)
14     {
15         MultiplayerHandler.instance.UserGameData = dataList;
16     }
17 }

最后就只需要在需要存取的地方,调用这两个静态函数就可以了