最近遇到了想通过scrip利用ORK FrameWork中的ISaveData存储自定义数据这方面的需求,网上的资料特别少,自己绕了两天才从这个泥潭里绕出来,所以本着自己年初给自己立下了规矩的原则,所以现在记下来,防止之后重蹈覆辙。

本以为这个接口像Unity自带的PlayerPrefs一样,Set/Get, 直观的存进去,直观的拿出来,结果证明自己还是too young too simple了。。。

虽然ISave的接口定义是这样的

namespace ORKFramework
{public interface ISaveData{void LoadGame(DataObject data);DataObject SaveGame();}
}

其中DataObject的定义是这样的:

namespace ORKFramework
{public sealed class DataObject{public DataObject();public bool Contains<T>(string key);public bool ContainsArray<T>(string key);public void Get<T>(string key, ref T value);public bool Get<T>(string key, out T[] value);public Dictionary<string, T[]> GetArrayData<T>(Type type);public Dictionary<string, T> GetData<T>(Type type);public ORKDataFile GetDataFile(string name, bool encrypt);public DataObject GetFile(string key);public DataObject[] GetFileArray(string key);public void Set<T>(string key, T value);public void Set<T>(string key, T[] value);public void SetArrayData<T>(Dictionary<string, T[]> data, Type type);public void SetData<T>(Dictionary<string, T> data, Type type);}
}

官网上说了,如果想实现存储自己自定义的数据就要实现ISaveData中的SaveGame和LoadGame这两个方法。官网给的例子是这样的:
Custom Component Save Data

using UnityEngine;
using ORKFramework;public class ComponentSaveTest : MonoBehaviour, IComponentSaveData
{// save key used to store different components of this classpublic string saveKey = "";// save valuespublic bool toggle = false;public float number = 0;public string text = "";public string GetSaveKey(){return saveKey;}// called when the component data is saved/storedpublic DataObject SaveGame(){DataObject data = new DataObject();data.Set("toggle", this.toggle);data.Set("number", this.number);data.Set("text", this.text);return data;}// called when the component data is loadedpublic void LoadGame(DataObject data){if(data != null){data.Get("toggle", ref this.toggle);data.Get("number", ref this.number);data.Get("text", ref this.text);}}
}

But,But,But,这是个坑啊!!!
当我们想要存储自定义数据的时候,实际上除了例子中的SaveGame和LoadGame,如果想将有某些特性的东西作为一个整体存进这里边的话,就需要在这个对象类中再实现一组SaveGame和LoadGame方法,相当于绕了一道。因为当这个对象作为一个整体的时候它只能是一个DataObject对象。(其实只要当时调试的时候我好好观察一下这个DataObject包含的属性就能明白了( ╯□╰ ))因为DataObject的私有成员只有:
audioData, eventData, fontData, gameObjectData, generalAssetData, guiSkinData, materialData, textureData, intData, intArrayData, floatData, floatArrayData, boolData, boolArrayData, stringData, stringArrayData, subData, subArrayData,其中subData就是DataObject。
所以我说我想用这个接口存一个GameObjectList,
ORK Framework说:你想的美!
つ﹏⊂

比如:
一所学校School有若干班级Class,一个Class包含若干学生Student,每个Student包含属性 ID(int), Name(string), Score(float), isLocal(bool)。
所以按照需求我需要存储School的属性,包括School Name(string),Location(string),一个包含若干Class的Data的subArrayData,而一个Class要有属性Class Name以及包含若干StudentData的subArrayData。

所以在StudentData类里实现的接口ISaveData为:

//StudentData类public DataObject SaveGame()
{DataObject data = new DataObject();data.Set("ID", this.id);data.Set("Name", this.name);data.Set("Score", this.score);data.Set("isLocal", this.isLocal);return data;
}public void LoadGame(DataObject dataObj)
{if(dataObj != null){dataObj.Get("ID", ref this.id);dataObj.Get("Name", ref this.name);dataObj.Get("Score", ref this.score);dataObj.Get("isLocal", ref this.isLocal);}
}

然后在Student类中再实现一遍这个接口

// Student类StudentData sData = new StudentData();
DataObjet data = new DataObje();
public DataObject SaveGame()
{data.Set("StudentData", sData.SaveGame());return data;
}public void LoadGame(DataObje dataObj)
{if(dataObj != null){dataObj.Get("StudentData", ref data);}
}public void Func()
{this.sData.LoadGame(data);//Then we can get the sData.id, sData.Name, sData.Score, sData.isLocal.//...
}

然后对于Class的Data也有一个ClassData类,在这里的SaveGame接口中调用Student类中的SaveGame,达到存储这个Class中Student信息的目的

//ClassData类List<DataObject> dObjList = new List<DataObject>();
DataObject[] dObjArray = new DataObject[100];      //假设有100人
DataObject data = new DataObje();
public DataObject SaveGame()
{for(int i = 0; i < student.Count; i++){if(!dObjList.Contains(student.SaveGame()){dObjList.Add(student.SaveGame());}}data.Set("StudentList", dObjList.ToArray());return data;
}public void LoadGame(DataObje dataObj)
{if(dataObj != null){dataObj.Get("StudentList", out dObjArray);  }
}

同样在Class类中还要再实现一遍属于Class类的SaveGame和LoadGame接口,和Student类中一样,就不敲了。

值得一提的还有当我LoadGame后取到之前存的数据后,想要实例化所有之前存的student,想要实例化就要知道prefab的名字,假设虽然student有100个,但是实际上工程内用的prefab只有4种,记录的数据是每种prefab实例化了25个放在地图的不同位置上,而DataObject的个数据的存储方式用的是Dictionary,又恰巧我存进去的key和prefab的名字完全不一样,但是其中student的一个属性type(string)是prefab的名字,那么问题就变成了在得到数据后怎么在Class类里取得student的type这个属性。
这就是DataObject中的另一个函数GetData了,它是根据类型返回一个DataObject中存储了所有该类型的Dictionary, 比如student中的name,type属性都是string,那么运用

Dictionary<string, string> sDataDic = sDataObjList[i].GetData<string>("abcd".GetType());
string stype = sDataDic["Type"];

估计还有更好的方法处理这个ORK Framework中这个存储数据的方式,但是我的脑子现在也就想到这些了,以后如果有新发现再做进一步优化。

ORK FrameWork - 自定义存储数据ISaveData接口相关推荐

  1. mysql标准化存储结构_Atitit.自定义存储引擎的接口设计 api 标准化 attilax 总结  mysql...

    Atitit.自定义存储引擎的接口设计api标准化attilax总结mysql 1.图16.1:MySQL体系结构 存储引擎负责管理数据存储,以及MySQL的索引管理.通过定义的API,MySQL服务 ...

  2. localStorage自定义存储数据方法及其使用总结

    localStorage 自定义一个localStorage本地存储数据 JSON.parse() JSON.stringify() localStorage例子 自定义一个localStorage本 ...

  3. python处理表格数据教程_python利用Excel读取和存储测试数据完成接口自动化教程...

    http_request2.py用于发起http请求 #读取多条测试用例 #1.导入requests模块 import requests #从 class_12_19.do_excel1导入read_ ...

  4. 【Grasshopper基础13】创建可在画布上自由传递的自定义类型数据(上)—— IGH_Goo接口的重要性及其实现

    接下来的两章,我们来介绍一下在之前章节尚未介绍到的,但却在Grasshopper中占据极其重要地位的另一批我们早就虎视眈眈但却还没想到理由要去触碰的电池们(左侧红色框指示): 是的,就是这一些带黑底的 ...

  5. SpringBoot集成Hasor-Dataway数据查询接口

    目录 一.前言 1.Hasor Core Core 容器框架 设计思想 特性 2.Hasor Web Web 框架 3.Hasor DB JDBC 框架 特性 4.Hasor DataQL DataQ ...

  6. 关于外部存储器件对存储数据的管理。

    一引子 :需要大量存储数据时,一般都不会使用单片机内部存储资源(单片机内部的eerom或者flash模拟eeprom只适合存储少量的数据).一般是通过I2C/SPI接口外部扩展eeprom或者flas ...

  7. .net core2.0下使用Identity改用dapper存储数据

    前言. 已经好多天没写博客了,鉴于空闲无聊之时又兴起想写写博客,也当是给自己做个笔记.过了这么些天,我的文笔还是依然那么烂就请多多谅解了.今天主要是分享一下在使用.net core2.0下的实际遇到的 ...

  8. 小程序服务器搭建前后端交互,微信小程序:request前后端交互 路由跳转 存储数据到本地和获取 小程序登入 授权...

    一 request前后端交互 基本样式 wx.request({ url:'test.php', //仅为示例,并非真实的接口地址 data: { x:'', y:''}, header: {'con ...

  9. 《连载 | 物联网框架ServerSuperIO教程》- 15.数据持久化接口的使用。附:3.2发布与版本更新说明。...

    1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...

  10. Entity Framework自定义迁移历史表(EF6以上)

    Entity Framework Customizing the Migrations History Table (EF6 onwards) Entity Framework自定义迁移历史表(EF6 ...

最新文章

  1. 中国厂商导致美国断网很稀奇?咱们早就被坑过了
  2. 测量角速度_锡膏的粘度如何正确鉴别和精确测量?
  3. 如何激活React的跟踪模式和打开日志记录
  4. import是引进外部函数吗_vue3已正式发布,你学了吗
  5. 【bzoj3119】Book
  6. opencv 一种灰度图像增强方式
  7. python封装sql脚本_flask-sqlalchemy如何使用原生的sql语句然后封装?
  8. pcs7 simatic batch v9.0_西门子V90 伺服STO安全功能注意事项
  9. IBM Machine Learning学习笔记——Time Series and Survival Analysis
  10. Xcode7中 添加 .dylib
  11. Redis配置和持久性
  12. nginx 工作原理
  13. 计算机网络课程设计——校园网的规划与设计
  14. python 公众号爬虫_微信公众号爬虫,看这个就足够了
  15. PT100温度传感器的工作原理
  16. 从0开始学习开发微信小程序(熟悉微信开发者工具页面,简单修改、添加一些内容)
  17. SQL归纳总结(1)
  18. vue中使用rem适配方案
  19. 贝叶斯网络应用实例一:胸部疾病诊所
  20. 【JVM翻译系列】「官方技术翻译」《A FIRST LOOK INTO ZGC》初探JVM-ZGC垃圾回收器

热门文章

  1. YDOOK: USB 转 TTL 模块 连线使用实例教程
  2. 能自动更新的万能周报模板,有手就会用!
  3. Matlab调用系统命令行利用Internet Download Manager(IDM)实现批量下载
  4. java dateutils工具类_Java日期工具类DateUtils详解(转)
  5. 支持nvme的linux_linux里的nvme驱动代码分析
  6. 查成语--每天10行python代码系列!
  7. 64位 mxcomponent_三菱MX Component 4.16S下载
  8. 青鸟影院的最后一部分
  9. 服务器挂软件系统,云服务器挂软件用什么系统
  10. 算法第四版 高清完整中文版(非纸质版)