游戏蛮牛学习群(纯技术交流,不闲聊):959392658
游戏蛮牛 手机端
开启辅助访问
 找回密码
 注册帐号

扫一扫,访问微社区

首页   >   博客   >   碎碎

xml,json,二进制的序列化和反序列化 热度 1

个人分类: 存档和读档 | 2018-7-10 11:05
0 个评论 | 阅读 121 | 收藏 | 举报
第一部分:xml,json,二进制方法

[code]csharpcode:

using UnityEngine;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using LitJson;
using System.Xml;
/// <summary>
/// UI游戏控制
/// 暂停游戏
/// 继续游戏
/// 新游戏
/// 退出游戏
/// </summary>
public class GameManager : MonoBehaviour {
    public static GameManager _instance;
    //是否暂停
    public bool isPaused = false;
    //菜单
    public GameObject menuGO;
    //怪物位置对象Target
    public GameObject[] targetsGO;
    private void Awake()
    {
        _instance = this;
       // Pause();
    }
    //暂停
    void Pause()
    {
        isPaused = true;
        menuGO.SetActive(true);
        Time.timeScale = 0;//时间为0 
        Cursor.visible = true;
    }
    //继续游戏----不暂停

	void UnPause()
    {
        isPaused = false;
        menuGO.SetActive(false);
        Time.timeScale = 1;
        Cursor.visible = false;
    }
    // Update is called once per frame
    void Update()
    {
        if(Input.GetKeyDown(KeyCode.Escape))
        {
            Pause();
        }
    }
    //保存游戏状态信息
    private Save CreatSaveGO()
    {
        //创建Save对象
        Save save = new Save();
        //遍历所有的Target
        //如果处于激活状态,保存该target的位置信息和激活状态的怪物类型
        foreach(GameObject targetGo in targetsGO)
        {
            TargetManager targetManager = targetGo.GetComponent<TargetManager>();
            if(targetManager.activeMonster!=null)
            {
                save.listTargetPos.Add(targetManager.targetPos);
                int type = targetManager.activeMonster.GetComponent<MonsterManager>().monsterType;
                save.listMonsterTypes.Add(type);
            }
        }
        //把射击数和得分存储到Save类中
        save.shootNum = UIManager.instance.shootNum;
        save.score = UIManager.instance.score;
        return save;
    }
    /// <summary>
    /// 通过读档信息重置游戏状态
    /// Save 对象中的
    /// 分数,射击数,怪物数,等
    /// </summary>
    private void SetGame(Save save)
    {
        //清空怪物,重置计时
        foreach(GameObject target in targetsGO)
        {
            target.GetComponent<TargetManager>().UpdateMonster();
        }
        //通过反序列化得到的Save对象中存储的信息,激活指定怪物
        for(int i = 0; i < save.listTargetPos.Count; i++)
        {
            int pos = save.listTargetPos[i];
            int type = save.listMonsterTypes[i];
            targetsGO[pos].GetComponent<TargetManager>().ActiveMonsterByType(type);
        }
        //更新UI显示
        UIManager.instance.shootNum = save.shootNum;
        UIManager.instance.score = save.score;
        //设置为未暂停状态,从保存的状态开始游戏
        UnPause();
    }
    /// <summary>
    /// 二进制方法
    /// 存档和读档
    /// </summary>
    private void SaveByBin()
    {
        //序列化过程(将Save对象转换为字节流)
        //创建Save对象并保存当前游戏状态
        Save save = CreatSaveGO();
        //创建二进制格式化程序
        BinaryFormatter bf = new BinaryFormatter();
        //创建一个文件流
        FileStream fileStream = File.Create(Application.dataPath + "/StreamingAssets" + "/byBin.txt");
        //二进制格式化程序的序列化方法来序列化Save对象,参数:(创建的文件流和需要序列化的对象)
        bf.Serialize(fileStream, save);
        //关闭文件流
        fileStream.Close();
        //判断文件是否存在,存在则保存成功
        if(File.Exists(Application.dataPath + "/StreamingAssets" + "/byBin.txt"))
        {
            UIManager.instance.ShowMsg("保存成功!");
        }
    }
    private void LoadByBin()
    {
        if(File.Exists(Application.dataPath + "/StreamingAssets" + "/byBin.txt"))
        {
            //反序列化过程
            BinaryFormatter bf = new BinaryFormatter();
            //打开一个文件
            FileStream fileStream = File.Open(Application.dataPath + "/StreamingAssets" + "/byBin.txt", FileMode.Open);
            //调用格式化程序的反序列化方法,将文件流转换成Savannah对象
            Save save = (Save)bf.Deserialize(fileStream);
            //关闭文件
            fileStream.Close();
            SetGame(save);
            UIManager.instance.ShowMsg("");
        }
        else
        {
            UIManager.instance.ShowMsg("文件不存在!");
        }
    }

    /// <summary>
    /// XML方法
    /// </summary>
    private void SaveByXml()
    {
        Save save = CreatSaveGO();
        //创建xml文件的存储路径
        string xmlPath=Application.dataPath + "/StreamingAssets" + "/byXml.txt";
        //创建xml文档
        XmlDocument xmlDoc = new XmlDocument();
        //创建根节点
        XmlElement root = xmlDoc.CreateElement("save");
        //设置根节点中的值
        root.SetAttribute("name", "saveFile1");
        //创建XmlElement
        XmlElement target;
        XmlElement targetPos;
        XmlElement monsterType;
        //遍历save中存储的数据,将数据转换成xml格式
        for(int i = 0; i < save.listTargetPos.Count; i++)
        {
            target = xmlDoc.CreateElement("target");
            targetPos = xmlDoc.CreateElement("targetPos");
            //设置 值
            targetPos.InnerText = save.listTargetPos[i].ToString();
            monsterType = xmlDoc.CreateElement("monsterType");
            monsterType.InnerText = save.listMonsterTypes[i].ToString();
            //设置节点间的层级关系root--target--(targetPos,monsterType)
            target.AppendChild(targetPos);
            target.AppendChild(monsterType);
            root.AppendChild(target);
        }
        //设置射击数和分数节点并设置层级关系xmldoc--root--target,shootNum,score
        XmlElement shootNum = xmlDoc.CreateElement("shootNum");
        shootNum.InnerText = save.shootNum.ToString();
        root.AppendChild(shootNum);

        XmlElement score = xmlDoc.CreateElement("score");
        score.InnerText = save.score.ToString();
        root.AppendChild(score);
        //添加到xml文档,保存
        xmlDoc.AppendChild(root);
        xmlDoc.Save(xmlPath);
        if(File.Exists(xmlPath))
        {
            UIManager.instance.ShowMsg("保存成功!");
        }
    }
    private void LoadByXml()
    {
        string xmlLoadPath= Application.dataPath + "/StreamingAssets" + "/byXml.txt";
        if(File.Exists(xmlLoadPath))
        {
            Save save = new Save();
            //加载xml文档
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(xmlLoadPath);
            //通过节点名称获取元素,结果为xmlNodelist类型
            XmlNodeList target = xmlDoc.GetElementsByTagName("target");
            //遍历target的所有节点,获取子节点的InnerText
            if(target.Count!=0)
            {
                foreach(XmlNode targetNode in target)
                {
                    //得到target位置
                    XmlNode targetPos = targetNode.ChildNodes[0];
                    int listTargetPos=int.Parse(targetPos.InnerText);
                    //把得到的值存储到save中
                    save.listTargetPos.Add(listTargetPos);
//得到怪物类型
                    XmlNode monsterType = targetNode.ChildNodes[1];
                    int listMonsterType = int.Parse(monsterType.InnerText);
                    //把得到的值存储到save中
                    save.listMonsterTypes.Add(listMonsterType);
                }

            }
            //得到存储的射击数和分数
            XmlNodeList shootNum = xmlDoc.GetElementsByTagName("shootNum");
            int shoot=int.Parse(shootNum[0].InnerText);
            save.shootNum = shoot;

            XmlNodeList score = xmlDoc.GetElementsByTagName("score");
            int scoreCount=int.Parse(score[0].InnerText);
            save.score = scoreCount;
            SetGame(save);
            UIManager.instance.ShowMsg("");
        }
        else
        {
            UIManager.instance.ShowMsg("文件不存在!");
        }
    }
    /// <summary>
    /// Json方法
    /// </summary>
    private void SaveByJson()
    {
        Save save = CreatSaveGO();
        //生成json文件路径设置
        string filePath = Application.dataPath + "/StreamingAssets" + "/byJson.json";
        //利用JsonMapper将save对象转换成json字符串
        string saveJsonStr = JsonMapper.ToJson(save);
        //将字符串写入文件
        StreamWriter sw = new StreamWriter(filePath);
        sw.Write(saveJsonStr);
        //关闭
        sw.Close();
        UIManager.instance.ShowMsg("保存成功!");

    }
    private void LoadByJson()
    {
        string filePath = Application.dataPath + "/StreamingAssets" + "/byJson.json";
        if(File.Exists(filePath))
        {
            //创建读取的StreanReader
            StreamReader sr = new StreamReader(filePath);
            //将json文件流赋值给jsonStr
            string jsonStr = sr.ReadToEnd();
            //关闭
            sr.Close();
            //将string类型转换成save对象
            Save save = JsonMapper.ToObject<Save>(jsonStr);
            SetGame(save);
            UIManager.instance.ShowMsg("");
        }
        else
        {
            UIManager.instance.ShowMsg("文件不存在!");
        }
    }
    //继续游戏
    public void Continue()
    {
        UnPause();
    }
    //新游戏
    public void NewGame()
    {
        foreach(GameObject targetGO in targetsGO)
        {
            targetGO.GetComponent<TargetManager>().UpdateMonster();
        }
        UIManager.instance.shootNum = 0;
        UIManager.instance.score = 0;
        UIManager.instance.ShowMsg("");
        UnPause();
    }
    //退出游戏
    public void QuitGame()
    {
        Application.Quit();
    }
    //保存游戏
    public void SaveGame()
    {
        //任意一个即可
      //  SaveByBin();
      //  SaveByJson();
        SaveByXml();
    }
    //加载游戏
    public void LoadGame()
    {
        //任意一个即可
      //  LoadByBin();
      //  LoadByJson();
        LoadByXml();
    }
}
第二部分:Save保存类:需要存储的数据

[code]csharpcode:

// 保存类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 序列化报错SerializationException: Type UnityEngine.MonoBehaviour in assembly
/// 改正方法
/// 删除继承MonoBehavior
/// 
/// </summary>
 //序列化
[System.Serializable]
//public class Save : MonoBehaviour {
    public class Save
    {
        //怪物位置
        public List<int> listTargetPos = new List<int>();
    //怪物 对象
    public List<int> listMonsterTypes = new List<int>();
    //射击数
    public int shootNum = 0;
    //得分
    public int score = 0;
}

第三部分:在属性面板上添加,target复制九个位置,给target添加
1、TargetManager类中:

[code]csharpcode:

//给Target所在位置 九个位置赋值,分别是0,1,2,。。。8
    public int targetPos;
2、MonsterManager类中:分别给四个怪物添加

[code]csharpcode:

 //怪物类型,0,1,2,3 
    public int monsterType;
3、UIManager类中:

[code]csharpcode:

//显示是否保存成功
    public Text MsgText;
    public void ShowMsg(string str)
    {
        MsgText.text = str;
    }

第四部分:xml文件

[code]xmlcode:

<save name="saveFile1">
  <target>
    <targetPos>2</targetPos>
    <monsterType>1</monsterType>
  </target>
  <target>
    <targetPos>7</targetPos>
    <monsterType>1</monsterType>
  </target>
  <target>
    <targetPos>8</targetPos>
    <monsterType>1</monsterType>
  </target>
  <shootNum>26</shootNum>
  <score>14</score>
</save>
第五部分:加载游戏是加载所保存的资源,反序列化。保存游戏是序列化方法,保存当前所存在的怪物类型和其父对象的位置信息。
1 0

作者的其他最新博客

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册帐号

个人分类

标签

阅读排行

评论排行

推荐博客

最新博客

返回顶部