Notifications
Article
游戏保存功能的简单实现 Implementation of Save Game
Published 4 days ago
4
0
保存游戏的实现 Implementation of Save Game

前言 Introduction

Unity 的保存功能,实际上可以看作是一个序列化的过程.通过脚本提取场景中需要保存的数据,写入Save文档.通过脚本读取Save文档中的数据,恢复存档所保存的状态.虽然可以使用BinaryFormatter实现存档的序列化,但BinaryFormatter序列化的细节并非令人理解,序列化后的数据量也十分臃肿.本文的实现方式使用了另一种手段,拥有以下几个特点:
  • 使用Dictionary字典的方式存取需要保存的数据对象.支持输出为Stream或者文件路径,对编写Save/Load脚本更为友好.
  • 遵循Unity的序列化原则,可以使用[Serializable](注意,任何自定义的对象必须添加Serializable特性才能参与序列化) [NonSerialized][SerializeField]编排是否参与序列化,也可以选择实现ISerializationCallbackReceiver接口,自定义序列化方式.继承自UnityEngine.Object的对象默认可被序列化.
  • 支持多态.不像Unity的序列化方式,本文的实现序列化并不由字段类型决定,而由字段的值决定.也就是说字段类型可以为抽象类或者接口.这在Unity的序列化过程是不可行的.
  • 额外添加对Dictionary<,>类型的支持.本文的实现 默认支持以下内置数据类型的序列化:null,bool,int,long,float,double,Enum,String,Byte[],Array,List<>,Dictionary<,>,Vector2,Vector3,Vector4,Rect,Quaternion,Color,Color32
  • null值 不会像unity序列化方式那样被序列化为一个新的对象.这在一定程度避免序列化死循环Bug的生成.

代码 Code

项目包含 CSerializedDocument.cs和CSerializedStream.cs两个附件类.
Contain these two .cs files to your project first.
创建并挂载脚本包含以下Demo代码可以检查存档序列化效果,源数据经过stream流写入并读出为目标数据.
Create and add the script below to check the demo effect. Source data is written to the stream and read as a Destination Data.
using System.Collections.Generic; using System.IO; using UnityEngine; public class CTestMonobehavior : MonoBehaviour { void Start() { MemoryStream aStream = new MemoryStream(); CSerializedDocument aSrc = new CSerializedDocument(); var aDic = new Dictionary<string, string>(); aDic["Key3"] = "love you too"; aSrc["Key1"] = 12; aSrc["Key2"] = "love you"; aSrc["Key3"] = aDic; Debug.Log("Source Data: Key1 =" + aSrc["Key1"]); Debug.Log("Source Data: Key2 =" + aSrc["Key2"]); Debug.Log("Source Data: Key3 =" + aDic["Key3"]); aSrc.MSaveTo(aStream); aStream.Position = 0; CSerializedDocument aDst = new CSerializedDocument(); aDst.MLoadFrom(aStream); Debug.Log("Destination Data: Key1 =" + aDst["Key1"]); Debug.Log("Destination Data: Key2 =" + aDst["Key2"]); Debug.Log("Destination Data: Key3 =" + ((Dictionary<string, string>)aDst["Key3"])["Key3"]); } }

Colin Gao
Programmer
1
Comments