• 【从零开始游戏开发】Unity 数据存储和读取 PlayerPrefs、序列化、JSON | 全面总结 |建议收藏


    你知道的越多,你不知道的越多 🇨🇳🇨🇳🇨🇳
    点赞再看,养成习惯,别忘了一键三连哦 👍👍👍
    文章持续更新中 📝📝📝


    1️⃣前言🔥🔥🔥

    Unity 中实现对游戏数据存储和读取的方法主要有这几种:

    使用本地持久化类 PlayerPrefs
    使用二进制的方法序列化和反序列化(Serialize / Deserialize)
    使用 Json 方法
    使用 XML 方法


    2️⃣数据场景🔥🔥🔥

    在 Demo 中分别使用这四种方法实现面板上数据的存储和读取
    在这里插入图片描述
    创建一个 Data 脚本用来序列化和反序列化,需要向这个类中添加需要保存的数据,最后也是需要从这个类中读取保存的数据

    需要存储和读取数据的脚本 Data

    [System.Serializable]
    public class Data
    {
        // 关卡/生命值/关卡得分
        public int levels;
        public int health;
        public int scores;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    向 Data 中存储和读取数据的方法

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    /// 
    /// 数据管理
    /// 
    public class DataManager : MonoBehaviour
    {
        // 创建 Data 对象,并添加需要保存的数据
        private Data GetGameData()
        {
            Data data = new Data();
            data.levels = CanvasManager.Instance.levels;
            data.health = CanvasManager.Instance.health;
            data.scores = CanvasManager.Instance.scores;
    
            return data;
        }
    
        // 向游戏中加载 Data 中保存的数据
        private void SetGameData(Data data)
        {
            CanvasManager.Instance.levels = data.levels;
            CanvasManager.Instance.health = data.health;
            CanvasManager.Instance.scores = data.scores;
            CanvasManager.Instance.DataUpdate();
        }
    }
    
    • 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

    3️⃣PlayerPrefs🔥🔥🔥

    Playerprefs 是 Unity 提供的一个用于本地数据持久化保存和读取的类

    原理就是利用 Key - Value 的方式将数据保存到本地(跟字典类似),然后通过代码实现数据保存、读取和更新的操作

    PlayerPrefs 只能保存 int 型、float 型和 string 型的数据,对于 bool 类型可以用 1/0 代替 真/假,实现保存的目的

    // 数据存储:PlayerPrefs
        private void SaveByPlayerPrefs()
        {
            PlayerPrefs.SetInt("Levels", CanvasManager.Instance.levels);
            PlayerPrefs.SetInt("Health", CanvasManager.Instance.health);
            PlayerPrefs.SetInt("Scores", CanvasManager.Instance.scores);
            PlayerPrefs.Save();
        }
    
        // 数据读取:PlayerPrefs
        private void LoadByPlayerPrefs()
        {
            if (PlayerPrefs.HasKey("Levels") && PlayerPrefs.HasKey("Health") && PlayerPrefs.HasKey("Scores"))
            {
                CanvasManager.Instance.levels = PlayerPrefs.GetInt("Levels");
                CanvasManager.Instance.health = PlayerPrefs.GetInt("Health");
                CanvasManager.Instance.scores = PlayerPrefs.GetInt("Scores");
                CanvasManager.Instance.DataUpdate();
            }
            else
                Debug.Log("- 未找到相应数据 -");
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    通过 PlayerPrefs 中的 SetInt() 将面板上的数据通过键值对的形式进行存储;然后通过 GetInt() 去读取保存下来的值

    面板上保存数据和加载数据按钮执行的方法

    // 保存游戏数据
        public void SaveGameData()
        {
            SaveByPlayerPrefs(); //通过 PlayerPrefs 方式保存
        }
    
        // 加载游戏数据
        public void LoadGameData()
        {
            LoadByPlayerPrefs(); //通过 PlayerPrefs 方式读取
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    4️⃣序列化与反序列化🔥🔥🔥

    保存的时候:

    首先创建二进制格式化程序,然后创建文件流,通过格式化程序将 Data 进行序列化并保存到本地

    读取的时候:

    先创建二进制格式化程序,然后创建文件流,通过格式化程序将 Data 反序列化出来,然后重新设置数据

    // 数据存储:二进制方法
        private void SaveByBin()
        {
            try
            {
                Data data = GetGameData();
                // 创建二进制格式化程序
                BinaryFormatter bf = new BinaryFormatter();
                using (FileStream fs = File.Create(Application.dataPath + "/SaveFiles" + "/ByBin.Txt"))
                {
                    // 将 data 序列化
                    bf.Serialize(fs, data);
                }
            }
            catch (System.Exception e)
            {
                Debug.Log(e.Message);
            }
        }
    
        // 数据读取:二进制方法
        private void LoadByBin()
        {
            try
            {
                BinaryFormatter bf = new BinaryFormatter();
                using (FileStream fs = File.Open(Application.dataPath + "/SaveFiles" + "/ByBin.Txt", FileMode.Open))
                {
                    // 将 data 反序列化
                    Data data = (Data)bf.Deserialize(fs);
                    SetGameData(data);
                }
            }
            catch (System.Exception e)
            {
                Debug.Log(e.Message);
            }
        }
    
    • 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

    文件流创建使用后需要及时关闭,即 fs.Close()

    在这里使用 using 指令的话就会自动关闭,省略了一步关闭的步骤

    面板上保存数据和加载数据按钮执行的方法

    // 保存游戏数据
        public void SaveGameData()
        {
            //SaveByPlayerPrefs(); //通过 PlayerPrefs 方式保存
            SaveByBin(); //通过二进制方式
        }
    
        // 加载游戏数据
        public void LoadGameData()
        {
            //LoadByPlayerPrefs(); //通过 PlayerPrefs 方式读取
            LoadByBin(); //通过二进制方式读取
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    5️⃣JSON🔥🔥🔥

    json 是一种轻量级的数据交换格式,使用 Json 在 Unity 中实现数据的存储和读取是非常方便的

    • 需要导入使用 Json 所需要的插件 *
    // 数据存储:Json
        private void SaveByJson()
        {
            Data data = GetGameData();
            string dataPath = Application.dataPath + "/SaveFiles" + "/ByJson.json";
            // 利用 JsonMapper 将 data 转换成字符串
            string dataStr = JsonMapper.ToJson(data);
            // 创建写入流写入数据
            StreamWriter sw = new StreamWriter(dataPath);
            sw.Write(dataStr);
            // 关闭流
            sw.Close();
        }
    
        // 数据读取:Json
        private void LoadByJson()
        {
            string dataPath = Application.dataPath + "/SaveFiles" + "/ByJson.json";
            // 判断路径文件
            if (File.Exists(dataPath))
            {
                // 创建读取流读取数据
                StreamReader sr = new StreamReader(dataPath);
                string jsonStr = sr.ReadToEnd();
                sr.Close();
                // 使用 JsonMapper 将得到的 jsonStr 转换为 data 对象
                Data data = JsonMapper.ToObject<Data>(jsonStr);
                SetGameData(data);
            }
            else
                Debug.Log("- 未找到相应文件 -");
        }
    
    • 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

    面板上保存数据和加载数据按钮执行的方法

    // 保存游戏数据
        public void SaveGameData()
        {
            //SaveByPlayerPrefs(); //通过 PlayerPrefs 方式保存
            //SaveByBin(); //通过二进制方式存储
            SaveByJson(); // 通过 Json 方式存储
        }
    
        // 加载游戏数据
        public void LoadGameData()
        {
            //LoadByPlayerPrefs(); //通过 PlayerPrefs 方式读取
            //LoadByBin(); //通过二进制方式读取
            LoadByJson(); //通过 Json 方式读取
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    🎁🌻🌼🌸 粉丝福利来喽 🎁🌻🌼🌸

    1. 免费领取海量资源 🎁
      简历自测评分表、Unity职级技能表、面试题库、入行学习路径等
    2. 《Unity游戏开发五天集训营 》50个名额 🎁
      我给大家争取到了 50个《游戏开发五天集训营 》名额,原价198,前50个免费
      扫码加入,暗号小听歌
      即可参加ARPG狼人战斗系统、饥荒生存类游戏开发、回合制RPG口袋妖怪游戏等游戏开发训练营
    3. 额外抽奖机会🎁
      参加游戏训练营、还有机会获得大厂老师在线面试指导、或者有机会获得价值1998元的《Unity极速入门与实战》课程
    🔻🔻🔻🔻 扫下方二维码,获取游戏开发福利,暗号小听歌 🔻🔻🔻🔻
  • 相关阅读:
    自然语言生成技术现状调查:核心任务、应用和评估(1)
    微信小程序如何在公共组件中改变某一个页面的属性值
    信息化疫情防控很有必要,老厂商出手了
    OPPO A2 Pro正式发布,媒介盒子多家媒体报道
    CMT2300A 433MHz SUB-1G无线收发芯片
    sqlalchemy从入门到熟悉(一)
    数据结构 | 数据结构的“基本概念”和“术语”
    Python基础(七)之数值类型集合
    数字孪生论文阅读笔记【2】
    序列超图的下一项推荐 笔记
  • 原文地址:https://blog.csdn.net/qq_21407523/article/details/127604885