Unity3D 保存游戏的几种方式

1. playerpref

官方文档:
https://docs.unity3d.com/ScriptReference/PlayerPrefs.html
保存位置:
http://blog.csdn.net/william_lv/article/details/39520367

2. 保存类

定义一个Save类,当想保存游戏的时候,创建一个类,并赋值。然后存储。当想读取游戏是,先读取文件并生成一个类,然后再赋值到游戏属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
[System.Serializable]
public class Save{
 
    public List<int> livingTargetPositions = new List<int>();
    public List<int> livingMonsterTypes = new List<int>();
 
    public int shootNum = 0;
    public int score = 0;
}
 //创建Save对象并存储当前游戏状态信息
    private Save CreateSaveGO()
    {
        //新建Save对象
        Save save = new Save();
        //遍历所有的target
        //如果其中有处于激活状态的怪物,就把该target的位置信息和激活状态的怪物的类型添加到List中
        foreach (GameObject targetGO in targetGOs)
        {
            TargetManager targetManager = targetGO.GetComponent<TargetManager>();
            if (targetManager.activeMonster != null)
            {
                save.livingTargetPositions.Add(targetManager.targetPosition);
                int type = targetManager.activeMonster.GetComponent<MonsterManager>().monsterType;
                save.livingMonsterTypes.Add(type);
            }
        }
        //把shootNum和score保存在Save对象中
        save.shootNum = UIManager._instance.shootNum;
        save.score = UIManager._instance.score;
        //返回该Save对象
        return save;
    }
//通过读档信息重置我们的游戏状态(分数、激活状态的怪物)
    private void SetGame(Save save)
    {
        //先将所有的targrt里面的怪物清空,并重置所有的计时
        foreach(GameObject targetGO in targetGOs)
        {
            targetGO.GetComponent<TargetManager>().UpdateMonsters();
        }
        //通过反序列化得到的Save对象中存储的信息,激活指定的怪物
        for(int i = 0; i < save.livingTargetPositions.Count; i++)
        {
            int position = save.livingTargetPositions[i];
            int type = save.livingMonsterTypes[i];
            targetGOs[position].GetComponent<TargetManager>().ActivateMonsterByType(type);
        }
 
        //更新UI显示
        UIManager._instance.shootNum = save.shootNum;
        UIManager._instance.score = save.score;
        //调整为未暂停状态
        UnPause();
    }

2.1. 保存到二进制文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
//二进制方法:存档和读档
private void SaveByBin() {
//序列化过程(将Save对象转换为字节流)
Save save = CreateSaveGO();  //创建Save对象并保存当前游戏状态
BinaryFormatter bf = new BinaryFormatter(); //创建一个二进制格式化程序
 FileStream fileStream = File.Create(Application.dataPath + "/StreamingFile" + "/byBin.txt"); //创建一个文件流
bf.Serialize(fileStream, save); //用二进制格式化程序的序列化方法来序列化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("存档文件不存在"); } }

2.2..JSON

需要使用第三方库 LitJson.dll

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
using LitJson;
    //JSON:存档和读档
    private void SaveByJson()
    {
        Save save = CreateSaveGO();
        string filePath = Application.dataPath + "/StreamingFile" + "/byJson.json";
        //利用JsonMapper将save对象转换为Json格式的字符串
        string saveJsonStr = JsonMapper.ToJson(save);
        //将这个字符串写入到文件中
        //创建一个StreamWriter,并将字符串写入文件中
        StreamWriter sw = new StreamWriter(filePath);
        sw.Write(saveJsonStr);
        //关闭StreamWriter
        sw.Close();
 
        UIManager._instance.ShowMessage("保存成功");
    }
 
    private void LoadByJson()
    {
        string filePath = Application.dataPath + "/StreamingFile" + "/byJson.json";
        if(File.Exists(filePath))
        {
            //创建一个StreamReader,用来读取流
            StreamReader sr = new StreamReader(filePath);
            //将读取到的流赋值给jsonStr
            string jsonStr = sr.ReadToEnd();
            //关闭
            sr.Close();
 
            //将字符串jsonStr转换为Save对象
            Save save = JsonMapper.ToObject<Save>(jsonStr);
            SetGame(save);
            UIManager._instance.ShowMessage("");
        }
        else
        {
            UIManager._instance.ShowMessage("存档文件不存在");
        }
    }

2.3.. XML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
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 < save.livingTargetPositions.Count; i++)
        {
            target = xmlDoc.CreateElement("target");
            targetPosition = xmlDoc.CreateElement("targetPosition");
            //设置InnerText值
            targetPosition.InnerText = save.livingTargetPositions[i].ToString();
            monsterType = xmlDoc.CreateElement("monsterType");
            monsterType.InnerText = save.livingMonsterTypes[i].ToString();
 
            //设置节点间的层级关系 root -- target -- (targetPosition, monsterType)
            target.AppendChild(targetPosition);
            target.AppendChild(monsterType);
            root.AppendChild(target);
        }
 
        //设置射击数和分数节点并设置层级关系  xmlDoc -- root --(target-- (targetPosition, monsterType), 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);
 
        xmlDoc.AppendChild(root);
        xmlDoc.Save(filePath);
 
        if(File.Exists(Application.dataPath + "/StreamingFile" + "/byXML.txt"))
        {
            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.livingTargetPositions.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("存档文件不存在");
        }
    }
posted @   多见多闻  阅读(731)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示