Unity数据持久化3——Json

概述

基础知识

Json文件格式

Json基本语法

练习

可以搜索:Json在线,复制代码进去解析是否写错了。

Excel转Json

C#读取存储Json文件

JsonUtility

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

[System.Serializable]
public class Student
{
    public int age;
    public string name;

    public Student(int age, string name)
    {
        this.age = age;
        this.name = name;
    }
}

public class Player
{
    public string name;
    public int age;
    public bool sex;
    public float testF;
    public double testD;

    public int[] ids;
    public List<int> ids2;
    public Dictionary<int, string> dic;
    public Dictionary<string, string> dic2;

    public Student s1;
    public List<Student> s2s;

    [SerializeField]
    private int privateI = 1;
    [SerializeField]
    protected int protectedI = 2;
}

public class RoleData
{
    public List<RoleInfo> list;
}

[System.Serializable]
public class RoleInfo
{
    public int hp;
    public int speed;
    public int volume;
    public string resName;
    public int scale;
}


public class Lesson1 : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        #region 知识点一 JsonUtility是什么
        //JsonUtility 是Unity自带的用于解析Json的公共类
        //它可以
        //1.将内存中对象序列化为Json格式的字符串
        //2.将Json字符串反序列化为类对象
        #endregion

        #region 知识点二 必备知识点——在文件中存读字符串
        //1.存储字符串到指定路径文件中
        //第一个参数 填写的是 存储的路径
        //第二个参数 填写的是 存储的字符串内容
        //注意:第一个参数 必须是存在的文件路径 如果没有对应文件夹 会报错
        File.WriteAllText(Application.persistentDataPath + "/Test.json", "Sunset存储的json文件");
        print(Application.persistentDataPath);

        //2.在指定路径文件中读取字符串
        string str = File.ReadAllText(Application.persistentDataPath + "/Test.json");
        print(str);

        #endregion

        #region 知识点三 使用JsonUtility进行序列化
        //序列化:把内存中的数据 存储到硬盘上
        //方法:
        //JsonUtility.ToJson(对象)
        Player p = new Player();
        p.name = "Sunset";
        p.age = 18;
        p.sex = true;
        p.testF = 1.5f;
        p.testD = 2.2;

        p.ids = new int[] { 1, 2, 3, 4, 5 };
        p.ids2 = new List<int>() { 1, 2, 3 };
        p.dic = new Dictionary<int, string>() { { 1, "123" }, { 2, "234" } };
        p.dic2 = new Dictionary<string, string> { { "3", "345" }, { "4", "456" } };
        p.s1 = null; //new Student(16, "Jack");
        p.s2s = new List<Student> { new Student(17, "Mary"), new Student(20, "Tom") };

        //JsonUtility提供了现成的方法 可以把类对象 序列化为 Json字符串
        string jsonStr = JsonUtility.ToJson(p);
        File.WriteAllText(Application.persistentDataPath + "/Player.json", jsonStr);

        //注意:
        //1.float序列化时看起来会有一些误差
        //2.自定义类需要加上序列化特性[System.Serializable]
        //3.想要序列化私有变量 需要加上特性[SerializeField]
        //4.JsonUtility不支持字典
        //5.IsonUtility存储null对象不会是null 而是默认值的数据
        #endregion

        #region 知识点四 使用JsonUtility进行反序列化
        //反序列化:把硬盘上的数据 读取到内存中
        //方法:
        //JsonUtility.FromJson(字符串)
        //读取文件中的 Json字符串
        jsonStr = File.ReadAllText(Application.persistentDataPath + "/Player.json");
        //使用Json字符串内容 转换成类对象
        Player p2 = JsonUtility.FromJson(jsonStr, typeof(Player)) as Player; //这种写法比较少用
        Player p3 = JsonUtility.FromJson<Player>(jsonStr); //这个写法常用

        //注意:
        //如果Json中数据少了,读取到内存中类对象中时不会报错
        #endregion

        #region 知识点五 注意事项
        //1.JsonUtilitu无法直接读取数据集合
        jsonStr = File.ReadAllText(Application.streamingAssetsPath + "/RoleInfo2.json");
        print(jsonStr);
        //List<RoleInfo> roleInfoList = JsonUtility.FromJson<List<RoleInfo>>(jsonStr);
        RoleData data = JsonUtility.FromJson<RoleData>(jsonStr);

        //2.文件编码格式需要是 UTF-8 不然无法加载
        #endregion

        #region 总结
        //1.必备知识点 —— File存读字符串的方法 ReadAllText 和 WriteAllText
        //2.JsonUtility提供的序列化、反序列化方法 ToJson 和 FromJson
        //3.自定义类需要加上序列化特性 [System.Serializable]
        //4.私有保护成员 需要加上 [SerializeField]
        //5.JsonUtility 不支持字典
        //6.JsonUtility 不能直接将数据反序列化为数据集合
        //7.Json文档编码格式必须是 UTF-8
        #endregion

    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

练习:

LitJson

using LitJson;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

public class Item2
{
    public int id;
    public int num;

    //LitJson反序列化时 自定义类型需要无参构造
    public Item2() { }

    public Item2(int id, int num)
    {
        this.id = id;
        this.num = num;
    }
}

public class PlayerInfo2
{
    public string name;
    public int atk;
    public int def;
    public float moveSpeed;
    public double roundSpeed;
    public Item2 weapon; 
    public List<int> listInt;
    public List<Item2> itemList;
    //public Dictionary<int, Item2> itemDic;
    public Dictionary<string, Item2> itemDic2;
}

public class Lesson2_Test : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {

        PlayerInfo2 p = new PlayerInfo2();
        p.name = "Sunstet";
        p.atk = 10;
        p.def = 3;
        p.moveSpeed = 20;
        p.roundSpeed = 20;
        p.weapon = new Item2(1, 10);
        p.listInt = new List<int>() { 1, 2, 3, 4, 5 };
        p.itemList = new List<Item2>() { new Item2(2, 20), new Item2(3, 30) };
        //p.itemDic = new Dictionary<int, Item2>() { { 1, new Item2(4, 40) }, { 2, new Item2(5, 50) } };
        p.itemDic2 = new Dictionary<string, Item2> { { "3", new Item2(6, 60) }, { "4", new Item2(7, 70) } };

        SaveData(p, "PlayerInfo2");

        PlayerInfo2 p2 = LoadData("PlayerInfo2");

    }

    public void SaveData(PlayerInfo2 p, string path)
    {
        string jsonStr = JsonMapper.ToJson(p);
        File.WriteAllText(Application.persistentDataPath + "/" + path + ".json", jsonStr);
        print(Application.persistentDataPath);
    }

    public PlayerInfo2 LoadData(string path)
    {
        string jsonSr = File.ReadAllText(Application.persistentDataPath + "/" + path + ".json");
        return JsonMapper.ToObject<PlayerInfo2>(jsonSr);
    }
}

JsonUtility 和 LitJson对比

总结

实践项目

需求分析 + Json数据管理类创建

存储和读取数据

using LitJson;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

/// <summary>
/// 序列化和反序列化Json时 使用的是哪种方案
/// </summary>
public enum JsonType
{
    JsonUtility,
    LitJson,
}

/// <summary>
/// Json数据管理类 主要用于进行 Json的序列化存储到硬盘 和 反序列化从硬盘中读取到内存中
/// </summary>
public class JsonMgr 
{
    private static JsonMgr instance = new JsonMgr();

    public static JsonMgr Instance => instance;

    public JsonMgr() { }

    //存储Json数据 序列化
    public void SaveData(object data, string fileName, JsonType type = JsonType.LitJson)
    {
        #region 自己写
        //string jsonStr = "";
        //switch (type)
        //{
        //    case JsonType.JsonUtility:
        //        jsonStr = JsonUtility.ToJson(data);
        //        break;
        //    case JsonType.LitJson:
        //        jsonStr = JsonMapper.ToJson(data);
        //        break;
        //}

        //File.WriteAllText(Application.persistentDataPath + "/" + fileName + ".json", jsonStr);

        #endregion

        //确定存储路径
        string path = Application.persistentDataPath + "/" + fileName + ".json";
        //序列化 得到Json字符串
        string jsonStr = "";
        switch (type)
        {
            case JsonType.JsonUtility:
                jsonStr = JsonUtility.ToJson(data);
                break;
            case JsonType.LitJson:
                jsonStr = JsonMapper.ToJson(data);
                break;
        }
        //把序列化的Json字符串 存储到指定路径的文件中
        File.WriteAllText(path, jsonStr);
    }

    /// <summary>
    /// 读取指定文件中的数据 反序列化
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="fileName"></param>
    /// <param name="type"></param>
    /// <returns></returns>
    public T LoadData<T>(string fileName, JsonType type = JsonType.LitJson) where T : new()
    {
        //确定从哪个路径读取
        //首先先判断 默认数据文件夹中是否有我们想要的数据 如果有 就从中获取
        string path = Application.streamingAssetsPath + "/" + fileName + ".json";
        //先判断 是否重载这个文件
        //如果不存在默认文件 就从 读写文件夹中去寻找
        if (!File.Exists(path))
            path = Application.persistentDataPath + "/" + fileName + ".json";
        //如果读写文件夹中都还没有 那就返回一个默认对象
        if (!File.Exists(path))
            return new T();

        //进行反序列化
        string jsonStr = File.ReadAllText(path);

        //把对象返回出去

        //数据对象
        T data = default(T);
        switch (type)
        {
            case JsonType.JsonUtility:
                data = JsonUtility.FromJson<T>(jsonStr);
                break;
            case JsonType.LitJson:
                data = JsonMapper.ToObject<T>(jsonStr);
                break;
        }

        return data;
    }

}

生成资源包

挖坑总结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/743550.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用Birdeye访问Sui上加密市场数据

是一个链上加密交易数据聚合器&#xff0c;于2024年4月开始整合Sui数据。 个人DeFi用户可以在Birdeye的首页找到丰富的数据&#xff0c;包括关于主流区块链上的tokens、交易和交易者钱包的详细信息。 Birdeye提供API和WebSockets数据服务&#xff0c;涵盖token价格和其他DeFi…

【jupyter notebook】解决打不开以及安装扩展插件的问题

文章目录 问题描述问题 1解决问题 2解决 问题描述 问题 1 在自定义的虚拟环境下&#xff0c;安装 jupyter notebook 6.4.12 版本时&#xff0c;报以下错误&#xff1a; 解决 查了一些 解决方法&#xff0c;执行以下命令即可解决&#xff1a; conda install traitlets5.9.0 …

PS系统教程27

Photoshop与Camera Raw Camera本身是作为插件存在的&#xff0c;处理对象Raw格式&#xff08;高清格式的图片标准&#xff09; JPG是压缩格式 Camera是源数据包&#xff0c;无损高清数据包 通道 通道只有黑白灰三种颜色&#xff0c;图层类似于前台&#xff0c;通道就是后台…

代码随想录算法训练营第七十天 | 108.冗余连接、109.冗余连接||

108.冗余连接 文字讲解&#xff1a;108. 冗余连接 | 代码随想录 解题思路 节点A 和节点 B 不在同一个集合&#xff0c;那么就可以将两个 节点连在一起 已经判断 节点A 和 节点B 在在同一个集合&#xff08;同一个根&#xff09;&#xff0c;如果将 节点A 和 节点B 连在一起就…

LabVIEW与PLC通讯方式及比较

LabVIEW与PLC之间的通讯方式多样&#xff0c;包括使用MODBUS协议、OPC&#xff08;OLE for Process Control&#xff09;、Ethernet/IP以及串口通讯等。这些通讯方式各有特点&#xff0c;选择合适的通讯方式可以提高系统的效率和稳定性。以下将详细介绍每种通讯方式的特点、优点…

Typora自动保存和找回未保存文件

在用typora做记录的时候没有手动保存&#xff0c;然后电脑崩了&#xff0c;还好有找回未保存文件功能&#xff0c;在这里存一下。 找到未保存的文件版本后将其内容复制到新文件即可。

【AI落地应用实战】如何高效检索与阅读论文——302.AI学术论文工具评测

一、引言 作为一名学术领域的探索者&#xff0c;我们都知道&#xff0c;检索和阅读论文是我们获取知识、启发思考、验证假设的基石&#xff0c;也是日常学习中必不可少的基本功之一。然而在浩瀚的学术海洋中&#xff0c;如何快速、准确地找到我们需要的论文&#xff0c;就像是…

Rust编写测试及控制执行

编写测试及控制执行 在 Rust 中&#xff0c;测试是通过函数的方式实现的&#xff0c;它可以用于验证被测试代码的正确性。测试函数往往依次执行以下三种行为&#xff1a; 设置所需的数据或状态运行想要测试的代码判断( assert )返回的结果是否符合预期 让我们来看看该如何使…

这几个PR小技巧你Get到了吗?

学习是永无止境的&#xff0c;需要不间断地学习&#xff0c;获取新知识。今天带来了5个PR小技巧&#xff0c;可以先收藏起来Adobe Premiere Pro 2024的获取查看Baidu Cloud 1、双倍稳定画面更舒适 一般来说大型电视剧、电影使用的拍摄设备都是非常高端的&#xff0c;不像我们…

Chrome插件:​Vue.js Devtools 高效地开发和调试

在现代前端开发中&#xff0c;Vue.js因其灵活性和性能优势&#xff0c;受到越来越多开发者的青睐。然而&#xff0c;随着项目规模的扩大&#xff0c;调试和优化变得愈发复杂。幸运的是&#xff0c;Vue.js Devtools的出现&#xff0c;为开发者提供了一套强大的工具集&#xff0c…

Unity 弧形图片位置和背景裁剪

目录 关键说明 Unity 设置如下 代码如下 生成和部分数值生成 角度转向量 计算背景范围 关键说明 效果图如下 来自红警ol游戏内的截图 思路&#xff1a;确定中心点为圆的中心点 然后 计算每个的弧度和距离 Unity 设置如下 没什么可以说的主要是背景图设置 代码如下 …

【Deep Learning】Self-Supervised Learning:自监督学习

自监督学习 本文基于清华大学《深度学习》第12节《Beyond Supervised Learning》的内容撰写&#xff0c;既是课堂笔记&#xff0c;亦是作者的一些理解。 在深度学习领域&#xff0c;传统的监督学习(Supervised Learning)的形式是给你输入 x x x和标签 y y y&#xff0c;你需要训…

Vue3 国际化i18n

国际化i18n方案 1. 什么是i18n2. i18n安装、配置及使用2.1 安装2.2 配置2.3 挂载到实例2.4 组件中使用2.5 语言切换 1. 什么是i18n i18n 是“国际化”的简称。在资讯领域&#xff0c;国际化(i18n)指让产品&#xff08;出版物&#xff0c;软件&#xff0c;硬件等&#xff09;无…

数据库系统体系结构-DBMS的三级模式结构、DBMS的工作方式、模式定义语言、二级映射

一、体系结构的概念 1、大多数DBMS遵循三级模式结构 &#xff08;1&#xff09;外模式 &#xff08;2&#xff09;概念模式 &#xff08;3&#xff09;内模式 2、DBMS的体系结构描述的应该是系统的组成结构及其联系以及系统结构的设计和变化的原则等 3、1978年美国国家标…

双向长短期记忆神经网络BiLSTM

先说一下LSTM LSTM 是一种特殊的 RNN&#xff0c;它通过引入门控机制来解决传统 RNN 的长期依赖问题。 LSTM 的结构包含以下几个关键组件&#xff1a; 输入门&#xff08;input gate&#xff09;&#xff1a;决定当前时间步的输入信息对细胞状态的影响程度。遗忘门&#xff…

大模型回归实业,少谈梦,多赚钱

前言 大家都知道美国现在AI很火&#xff0c;但是现在火到已经有点看不懂的地步了。 苹果前脚在WWDC24上公布了自己在AI上的新进展&#xff0c;隔天市值就上涨了2142亿美元。而以微软为首的美股“Big 7”的市值更是达到史无前例的14万亿&#xff0c;占据标普500的32%。 冷静下…

【吊打面试官系列-Mysql面试题】你可以用什么来确保表格里的字段只接受特定范围里的值?

大家好&#xff0c;我是锋哥。今天分享关于 【你可以用什么来确保表格里的字段只接受特定范围里的值?】面试题&#xff0c;希望对大家有帮助&#xff1b; 你可以用什么来确保表格里的字段只接受特定范围里的值? 答&#xff1a;Check 限制&#xff0c;它在数据库表格里被定义&…

bigtop gradle 任务依赖关系

./gradlew deb 会编译ubuntu的所有deb包 任务deb会依赖17个任务&#xff0c;它们会按字母排序执行&#xff0c;如下&#xff1a; alluxio-deb bigtop-groovy-deb bigtop-jsvc-deb bigtop-utils-deb flink-deb hadoop-deb hbase-deb hive-deb kafka-deb livy-deb phoenix-deb …

网络构建关键技术_2.IPv4与IPv6融合组网技术

互联网数字分配机构&#xff08;IANA&#xff09;在2016年已向国际互联网工程任务组&#xff08;IETF&#xff09;提出建议&#xff0c;要求新制定的国际互联网标准只支持IPv6&#xff0c;不再兼容IPv4。目前&#xff0c;IPv6已经成为唯一公认的下一代互联网商用解决方案&#…

【Linux】解决windows下文件到linux下文件格式^M的问题之tr命令、sed命令

方法一&#xff1a; sed -i s/^M/ /g 方法二 &#xff1a; tr -d "^M" 1. 删除 -d 2. 替换字符