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 }
最后就只需要在需要存取的地方,调用这两个静态函数就可以了