扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
使用Unity怎么实现一个游戏存档框架,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。
创新互联是一家专注于做网站、成都网站制作与策划设计,铁锋网站建设哪家好?创新互联做网站,专注于网站建设十载,网设计领域的专业建站公司;建站业务涵盖:铁锋等地区。铁锋做网站价格咨询:18982081108ISavable,表示这个类型可以存档
public interface ISavable{ uint Id {get; set;} Type DataType {get;} // 存档数据类型 Type DataContainerType {get;} // 存档数据容器类型 void Read(object data); void Write(object data);}
ISavableContainer,用来返回一组ISavable的容器:
public interface ISavableContainer{ IEnumerable
IId, 具有Id的接口:
public interface IId{ uint Id {get; set;}}
SaveEntity, 这是一个MonoBehaviour,将这个组件放到需要存档的GameObject上就可以实现该GameObject的存档了,这是最核心的类之一:
public class SaveEntity : MonoBehaviour{ public void Save(SaveDataContainer container){ foreach(ISavable savable in GetSavables()){ if(savable.DataContainerType = container.GetType()){ IId newData = Activator.CreateInstance(savable.DataType) as IId; newData.Id = savable.Id; savable.Write(newData); container.SetData(newData); } } } public void Load(SaveDataContainer container){ foreach(ISavable savable in GetSavables()){ if(savable.DataContainerType = container.GetType()){ IId data = container.GetData(savable.Id); savable.Read(data); } } } public IEnumerable
SaveFile代表一个文件
[Serializable]public class SaveFileData{ public uint CurId; public string DataContainer;} // 代表一个存档文件public class SaveFile: MonoBehaviour{ // 包含实际数据的数据类 private SaveDataContainer _saveDataContainer; private uint _curId; public string Path{get;set;} public SaveDataContainer SaveDataContainer{get{return _saveDataContainer;}} private uint NextId{get{return ++_curId;}} // 得到场景里所有的SaveEntity private IEnumerable
SaveDataContainer:
// 这个类型存储了实际的数据,相当于是一个数据库[Serializable]public class SaveDataContainer{ // 这个中存储这实际物体的数据,需要将这个字典转换成数组并序列化 private Dictionary
好了,框架就讲到这里,接下来实现示例代码:
Unit:
[Serializable]public class UnitSave:IId{ [SerializeField] private uint _id; public uint PrefabId; public uint InventoryId; public int Hp; public int Level; public uint Id {get{return _id;}set{_id = value;}}} public class Unit:MonoBehaviour, ISavable{ public int Hp; public int Level; public int PrefabId; public Inventory Inventory; public uint Id{get;set;} ISavable.DataType{get{return typeof(UnitSave);}} ISavable.DataContainerType{get{return typeof(ExampleSaveDataContainer);}} ISavable.Read(object data){ UnitSave save = data as UnitSave; Hp = save.Hp; Level = save.Level; } ISavable.Write(object data){ UnitSave save = data as UnitSave; save.Hp = Hp; save.Level = Level; save.InventoryId = Inventory.Id; }}
Inventory:
[Serializable]public class InventorySave:IId{ [SerializeField] private uint _id; public uint UnitId; public uint[] Items; public uint Id{get{return _id;}set{_id = value;}}} public class Inventory:MonoBehaviour, ISavable, ISavableContainer{ public Unit Unit; public List
Item:
[Serializable]public ItemSave: IId{ [SerializeField] private uint _id; public uint PrefabId; public int Count; public uint Id{get{return _id;}set{_id = value;}}} // 道具并不是继承自MonoBehaviour的,是一个普通的类public class Item:ISavable{ // 道具源数据所在Prefab,用于重新创建道具 public uint PrefabId; public int Count; public uint Id {get;set;} public uint Id{get;set;} ISavable.DataType{get{return typeof(ItemSave);}} ISavable.DataContainerType{get{return typeof(ExampleSaveDataContainer));}} ISavable.Read(object data){ ItemSave save = data as ItemSave; Count = save.Count; } ISavable.Write(object data){ ItemSave save = data as ItemSave; save.PrefabId = PrefabId; save.Count = Count; }}
ExampleSaveDataContainer:
[Serializable]public class ExampleSaveDataContainer: SaveDataContainer, ISerializationCallbackReceiver { public UnitSave[] Units; public ItemSave[] Items; public InventorySave[] Inventories; public void OnBeforeSerialize(){ // 将Data字典中的数据复制到数组中,实现略过 } public void OnAfterDeserialize(){ // 将数组中的数据赋值到Data字典中,实现略过 }}
ExampleGame:
public class ExampleGame:MonoBehaviour{ public void LoadGame(SaveFile file){ // 从文件中读入数据到SaveDataContainer file.LoadFromFile
使用方法:
给单位Prefab中的Unit组件和Inventory组件所在的GameObject上放SaveEntity组件即可。
思考问题:
1.扩展功能,让SaveFile包含一个SaveDataContainer数组,这样子可以实现包含多个数据容器(数据库)的情况2.对SaveFile存储内容进行压缩,减少存储体积3.SaveFile存储到文件时进行加密,避免玩家修改存档4.如何避免存储时候卡顿
存储过程:
1.从场景中搜集数据到SaveFile中(SaveFile.Save),得到一个SaveFileData的数据2.将SaveFileData序列化成一个json字符串3.对字符串进行压缩4.对压缩后的数据进行加密5.将加密后的数据存储于文件
可以发现,只要完成第1步,得到一个SaveFileData,实际上就已经完成了存档了,接下来实际上就是一个数据转换的过程。所以,这也给出了避免游戏卡顿的一种方法:
完成第一步之后,将后面的步骤全部都放到另一个线程里面处理。实际上,第一步的速度是相当快的。往往不会超过50ms,可以说,卡顿并不会很明显。
看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注创新互联行业资讯频道,感谢您对创新互联网站建设公司,的支持。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流