这节介绍使用 Unity 自带的 PlayerPrefs 机制保存游戏数据。
1. 实现保存功能
我们新建一个 C# 脚本,命名为 SaveManager,它也是一个单例类。
如代码清单 1 所示,我们编写了基础的 Save() 和 Load() 函数,它针对于所有类型的类。我们通过 JsonUtility.ToJson 来将类转化成 json 字符串;JsonUtility.FromJsonOverwrite 将 json 字符串中的内容覆盖到现有类上。PlayerPrefs.SetString 和 PlayerPrefs.GetString 可以写入字符串和获取字符串,即可以用于我们生成的 json 文本。PlayerPrefs.Save 用于保存数据,实现可持久存储。
视频中是把键的名字用对象名称指定。本地实验下来发现,预制体实例化出来的对象名称会额外加上 "Clone" 字样,导致键不匹配。
这边将键名称写死。
代码清单 1 中的 SavePlayerData() 和 LoadPlayerData() 用于存储和加载角色信息数据,包含人物数值和攻击数值。需要注意的是,作用的类需要是 ScriptableObject。
需要注意读写需要作用在 ScriptableObject 类上。
发现之前跟着教程的做法,针对 ScriptableObject 的封装有点冗余。
1.1 保存测试
在代码清单 1 中,我们在 Update() 函数中编写测试代码:按下 S 键保存,按下 L 键加载。我们可以在进入游戏后保存人物数据。然后打怪让人物信息发生变化后,再加载之前保存的数据,看界面上 UI 是否按预期显示。
在 Windows 系统上,PlayerPrefs 相关内容存储在注册表上。如图 1 所示,我们可以找到地方,具体查看一下键值。
2. 完善场景切换逻辑
切换不同场景时,人物是通过预制体实例化出来的,所以需要同步传送前的人物数据信息。
如代码清单 2 所示,我们在场景加载之前保存当前人物角色数据,到了新场景后再加载之前保存的数据,达到数据同步的效果。
特别需要注意时序的问题,需要是这样的时序:保存人物数据;人物对象 Disable,取消 GameManager 的注册;生成新人物对象,在 GameManager 上注册;加载人物数据。即加载的数据需要作用在最新的人物对象上。
上一篇文章中在地下城场景中还没有人物信息 UI。添加的方式也很简单,将原先场景中的人物信息 UI 存为预制体,再拖拽到新场景中即可,相关逻辑是通用的。
新场景添加完人物信息 UI 之后,测试的话就很方便。只需要看传送到新场景后人物信息是否和传送前一致。