Unity中使用的四种存档和读档方式 |
您所在的位置:网站首页 › 如何设置存档和隐藏 › Unity中使用的四种存档和读档方式 |
这里会列举四种存档方式,并且以简单的项目展示出效果。 这里我会写的简单易懂些,希望大家学到的是存档与读档的逻辑。 1.第一种方式: Unity自带的存档方式 干货:PlayerPrefs:数据持久化方案。 采用键值对的方式对数据进行存储。 eg:PlayerPrefs.SetInt("Index",1); 可以存储Int, Float, String类型的数据。 eg:PlayerPrefs.SetFloat("Height",183.5f); PlayerPrefs.SetString("Name","Tom"); 获取数据: eg:PlayerPrefs.GetInt("Index"); Serialization(序列化),可以用来将对象转化为字节流。 Deserialization(反序列化),可以用来将字节流转换为对象。项目阐述: 首先,我们在一个空项目中新建一个Toggle,并给Canvas添加一个 Audio Source 组件和一个脚本,脚本 名根据个人需求,(我这里是MusicManager)效果图如下:音乐素材资源,百度网盘链接:https://pan.baidu.com/s/1201WQaMSr1NUgZcvcrzG1A 提取码:rvqq
最后,记得赋值: 项目阐述: 项目百度网盘链接:链接:https://pan.baidu.com/s/1Xxn7yXTkFTEq65Vlz0tojg 提取码:9p4q 剩余的三种方式都以该项目阐述。 参考博客:http://blog.csdn.net/y1196645376/article/details/52541882Ps:项目百度网盘链接里面有半成品和成品,半成品没有保存和加载功能,这里不建议小伙伴们拿着半成品跟着我的博客做, 希望小伙伴们学的是一种存储的思路。 参考博客是一位大佬写的, 小伙伴们可以用Unity打开成品里面的GameManager脚本,参照着那篇博客食用。也可以接着看完。 项目介绍: 1.UI层面解锁:这个游戏是一个第一人称射击游戏,当我们控制鼠标发射子弹击中箱子后,射击数会增加,得分 会增加。 1.1 当我们菜单栏显示时,即为游戏的暂停状态,游戏内的物品不可交互。不可射击,箱子不可生成。 1.2 当我们每发射一次子弹,则发射数自增1,击中箱子后得分自增1. 2.GameObject层面解锁: 2.1 箱子 这里箱子用协程写了随机生成、随机生命周期(未被击中时)、击中后0.3s失活。 2.2 箱子 这里箱子的种类有4种,红、橙、黄、绿,各个标志位之间的生成互不影响。种类编号0至3. 2.3 箱子 这里箱子一共有5个标志位,从左至右序号为 0至4。 2.4 枪 这里枪发射子弹的CD为1s一次,而箱子被击中后会在0.3s后消失,这就避免了每个箱子被击 中两次,从而避免了重复加分。代码展示:首先是二进制方法 我们先是Save方法,用于存储当前游戏状态信息. using System.Collections.Generic; [System.Serializable] public class Save { public List livingTargetPointions = new List(); public List livingMonsterTypes = new List(); public int shootNum = 0; public int score = 0; } 这个方法是用于记录箱子的状态信息,存储到Save方法中. // 按照给定的怪物类型激活怪物 // 停止所有协程 // 将当前激活状态的箱子(如果有的话)转为为激活状态 // 激活给定类型的怪物 public void ActivateMonsterByType(int type) { StopAllCoroutines(); // 当保存游戏后场景中仍然有箱子, 先将其隐藏,然后让activeMonster为null , // 等加载时 赋给 activeMonster 保存前的箱子类型 , 然后让其显示并开启 BoxCollider // 然后开启死亡协程 if (activeMonster != null) { activeMonster.GetComponent().enabled = false; activeMonster.SetActive(false); activeMonster = null; } activeMonster = monsters[type]; activeMonster.SetActive(true); activeMonster.GetComponent().enabled = true; StartCoroutine(DeathTimer()); } Save中的存储信息通过该方法反馈给每一个读档方式。这个方法是读档方法的辅助方法。每个读档方法方法都要调 用它。 // 通过读档信息重置我们的游戏状态 (分数、激活状态的怪物) private void SetGame(Save save) { // 先将所有的target里面的怪物清空,并重置所有的计时 foreach (GameObject targetGO in targetsGOs) { targetGO.GetComponent().UpdateMonsters(); } // 通过反序列化得到的Save 对象中存储的信息,激活指定的怪物 for (int i = 0; i // 序列化过程 (将Save 对象转换为字节流) // 创建Save 对象 并 保存当前游戏状态 Save save = CreateSaveGO(); // 创建一个二进制格式化程序 BinaryFormatter bf = new BinaryFormatter(); // 创建一个文件流 FileStream fileStream = File.Create(Application.dataPath + "/StreamingFile" + "/byBin.txt"); // 用二进制格式化程序的序列化方法 来 序列化Save对象 // 参数:创建的文件流和需要序列化的对象 bf.Serialize(fileStream,save); // 关闭流 fileStream.Close(); // 如果文件存在,则显示保存成功 if (File.Exists(Application.dataPath + "/StreamingFile" + "/byBin.txt")) { UIManager._Instance.ShowMessage("保存成功!"); } } private void LoadByBin() { if (File.Exists(Application.dataPath + "/StreamingFile" + "/byBin.txt")) { // 反序列化过程 // 创建一个二进制格式化程序 BinaryFormatter bf = new BinaryFormatter(); // 打开一个文件流 FileStream fileStream = File.Open(Application.dataPath + "/StreamingFile" + "/byBin.txt", FileMode.Open); // 调用格式化程序的反序列化方法,将文件流转换为Save 对象 Save save = (Save)bf.Deserialize(fileStream); // 关闭文件流 fileStream.Close(); SetGame(save); UIManager._Instance.ShowMessage(" "); } else { UIManager._Instance.ShowMessage("存档文件不存在!"); } }这里我的射击数是 14 得分是7 ,已经点击保存游戏,我的 Project 面板下的 StreamingFile文件夹就会自动创建一个 byBin.txt文件。看下图 公共部分代码我就不再重复了,辅助工作还是和二进制的一样。 Json 读档和存档 Json 需要一个系统性的Json文件 (半成品和成品中都有,我就不发链接了)看图,先导入该文件再添加(using LitJson;)命名空间. 保存路径规则 还是一样的 . 读档路径必须和存档路径相同,绝大多数我们写这种功能代码时,都是先写存档再读档. using LitJson; // 此命名空间需添加 // Json: 存档和读档 private void SaveByJson() { Save save = CreateSaveGO(); string filePath = Application.dataPath + "/StreamingFile" + "/byJson.txt"; // 利用 JsonMapper 将save 对象转换Wie Json 格式的字符串 string saceJsonStr = JsonMapper.ToJson(save); // 将这个字符串写入到文件中 // 创建一个StreamWriter,并将字符串写入文件中 StreamWriter sw = new StreamWriter(filePath); sw.Write(saceJsonStr); // 关闭 StreamWrite sw.Close(); UIManager._Instance.ShowMessage("保存成功!"); } private void LoadByJson() { string filePath = Application.dataPath + "/StreamingFile" + "/byJson.txt"; if (File.Exists(filePath)) { // 创建一个 StreamReader, 用来读取流 StreamReader sr = new StreamReader(filePath); // 将读取到的流赋值给 jsonStr string jsonStr = sr.ReadToEnd(); // 关闭 sr.Close(); // 将字符串jsonStr 转换为Save 对象 Save save = JsonMapper.ToObject(jsonStr); SetGame(save); UIManager._Instance.ShowMessage(" "); } else { UIManager._Instance.ShowMessage(" 存档文件不存在!"); } } 先导入该文件再添加(using LitJson;)命名空间. 这种方法可以看的懂读档。下图.
可以用 文本打开 也可以用VS. 下面仔细看 射击数和得分是没有问题的。 标志位1 中的橙箱子激活和标志位3的黄箱子激活,所以标志位序号为 1,3。我们来看一下橙箱子和黄箱子的编号。 需要using System.Xml; 命名空间。 代码如下: // Xml: 存档和读档 private void SaveByXml() { Save save = CreateSaveGO(); // 创建Xml 文件的存储路径 string filePath = Application.dataPath + "/StreamingFile" + "/byXML.txt"; // 创建XML 文档 XmlDocument xmlDoc = new XmlDocument(); // 创建根节点, 即最上层节点 XmlElement root = xmlDoc.CreateElement("save"); // 设置根节点中的值 root.SetAttribute("name","saveFile1"); // 创建XmlElement XmlElement target; XmlElement targetPosition; XmlElement monsterType; // 遍历 save中存储的数据,将数据转换成XML格式 for (int i =0; i UIManager._Instance.ShowMessage("保存成功!"); } } private void LoadByXml() { string filePath = Application.dataPath + "/StreamingFile" + "/byXML.txt"; if (File.Exists(filePath)) { Save save = new Save(); // 加载XML 文档 XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(filePath); // 通过节点名称来获取元素,结果为XmlNodeList类型 XmlNodeList targets = xmlDoc.GetElementsByTagName("target"); // 遍历所有的 target 节点,并获取子节点和子节点的InnerText if (targets.Count != 0) { foreach (XmlNode target in targets) { XmlNode targetPosition = target.ChildNodes[0]; int targetPositionIndex = int.Parse(targetPosition.InnerText); // 把得到的值存储到 save 中 save.livingTargetPointions.Add(targetPositionIndex); XmlNode monsterType = target.ChildNodes[1]; int monsterTypeIndex = int.Parse(monsterType.InnerText); save.livingMonsterTypes.Add(monsterTypeIndex); } } // 得到存储的射击数 XmlNodeList shootNum = xmlDoc.GetElementsByTagName("shootNum"); int shootNumCount = int.Parse(shootNum[0].InnerText); save.shootNum = shootNumCount; XmlNodeList score = xmlDoc.GetElementsByTagName("score"); int scoreCount = int.Parse(score[0].InnerText); save.score = scoreCount; SetGame(save); UIManager._Instance.ShowMessage(" "); } else { UIManager._Instance.ShowMessage("存档文件不存在"); } } 我先带大家理出答案,我们再看自动创建的byXML.txt文件。当我保存游戏后 ,场景中是有4个箱子的。标志位序号为 0,1,2,3 。(红橙黄绿)箱子编号为: Scene 面板从右至左,Game窗口从左至右,以Game窗口为准, 橙箱子 1 黄箱子 2 红箱子 0 橙箱子1. 自动创建的byXML文件.
感谢小伙伴们的观看,没看懂的话去看我上面的那条链接大佬的博客。拜拜! |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |