Unity数据持久化3——Json

news2024/10/9 13:55:04

概述

基础知识

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;
    }

}

生成资源包

挖坑总结

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PCM、WAV,立体声,单声道,正弦波等音频素材

1&#xff09;PCM、WAV音频素材&#xff0c;分享给将要学习或者正在学习audio开发的同学。 2&#xff09;内容属于原创&#xff0c;若转载&#xff0c;请说明出处。 3&#xff09;提供相关问题有偿答疑和支持。 常用的Audio PCM WAV不同采样率&#xff0c;不同采样深度&#…

Mac安装多版本node

Mac下使用n模块去安装多个指定版本的Node.js&#xff0c;并使用命令随时切换。 node中的n模块是&#xff0c;node专门用来管理node版本的模块&#xff0c;可以进行node版本的切换&#xff0c;下载&#xff0c;安装。 1.安装n npm install -g n 2.查看版本 n --version 3.展…

sql:between and日期毫秒精度过多导致的查询bug

复现 一般情况下&#xff0c;前端传的日期值大多都是yyyy-MM-dd HH:mm:ss(标准格式)&#xff0c;比如2024-06-25 10:49:50&#xff0c;但是在测试环境&#xff0c;测试人员测出了一个带毫秒的日期&#xff1a;比如2024-06-25 10:49:50.9999999 这种情况下会出现查询bug SELEC…

《昇思25天学习打卡营第2天 | 张量 Tensor》

《昇思25天学习打卡营第2天 | 张量 Tensor》 《昇思25天学习打卡营第2天 | 张量 Tensor》 《昇思25天学习打卡营第2天 | 张量 Tensor》什么是张量&#xff08;Tensor&#xff09;张量的创建方式根据数据直接生成从NumPy数组生成使用init初始化器构造张量继承另一个张量的属性&a…

OVS:standalone模式下测试添加tag之后的vlan隔离

目录 1.新建一个ovs交换机 2.创建两个端口&#xff0c;分别配置tag2000和tag2001 3.为网桥德默认internal端口配置IP地址 4.创建两个ns 5.对两个ns进行手动的网络配置 6.再端口处于不通tag时检测两个ns之间的连通性结果为不通-ping--fail 7.将两个端口p1,p2 的tag设成一致…

office宏绕过杀软诱导点击实现主机控制

绕过防病毒扫描已经成为 BHIS&#xff08;Black Hills Information Security&#xff09;的一项运动。当我们为客户进行指挥控制&#xff08;C2&#xff09;测试时&#xff0c;我们从内部网络上的主机开始&#xff0c;创建一个反向连接到我们的C2服务器。然后&#xff0c;我们继…

Mysql中varchar类型数字排序不对踩坑记录

场景 在进行表设计时将版本号字段设计了为varchar类型&#xff0c;尽量从表设计阶段将数字类型列设计为int型。 再进行排序时如果版本号累计到了10及以上&#xff0c;那么再进行排序时则会出现问题。 比如下面执行排序时发现10被排在了第一位。 这是因为 varchar类型对数字…

Lua流媒体服务器支持(MP4视频、桌面直播、摄像头)

本来在做FFMPEG的项目&#xff0c;忽然想到Lua封装FFMPEG与SRS实现一个简易的直播网站何尝不是一个大胆的想法。 示例为初级版本&#xff0c;主要是用来验证可行性和功能性DEMO 演示效果&#xff1a; Lua流媒体直播服务器(支持MP4、桌面直播、摄像头)_哔哩哔哩_bilibili 代码简…

①分析胃癌组蛋白脱乙酰酶HDS模型-配对转录组差异

目录 HDS评分构建 ①数据加载 ②评分计算 做样本及评分展示图 ①数据处理 ②进行作图 分析配对的单细胞及转录组胃癌数据的 HDS评分,数据源于gastric-cancer - GitCode①胃癌单细胞和配对转录组揭示胃肿瘤微环境(文献和数据)_代码笔记:处理迄今为止最大的单细胞胃癌数…

【漏洞复现】通天星CMSV6——sql注入漏洞

声明&#xff1a;本文档或演示材料仅供教育和教学目的使用&#xff0c;任何个人或组织使用本文档中的信息进行非法活动&#xff0c;均与本文档的作者或发布者无关。 文章目录 漏洞描述漏洞复现测试工具 漏洞描述 通天星CMSV6小于7.33.0.7版本存在接口pointManage存在注入漏洞&…

2023年SWPU NSS 秋季招新赛 (校外赛道)-没做出来的writeup

web 学习一下&#xff1a;[SWPUCTF 2023 秋季新生赛]——Web方向 详细Writeup-CSDN博客 查查need 看这个大佬的手工注入&#xff0c;nb呀 文章列表 | NSSCTF 其实也是可以使用sqlmap一把梭哈&#xff01; 看了教程&#xff1a;SQLmap使用教程图文教程&#xff08;非常详细…

H2RSVLM:引领遥感视觉语言模型的革命

随着人工智能技术的飞速发展&#xff0c;遥感图像理解在环境监测、气候变化、粮食安全和灾害预警等多个领域扮演着越来越重要的角色。然而&#xff0c;现有的通用视觉语言模型&#xff08;VLMs&#xff09;在处理遥感图像时仍面临挑战&#xff0c;主要因为遥感图像的独特性和当…

优选算法2

五、位运算 常见位运算总结 &&#xff1a;有0就是0&#xff1b; |&#xff1a;有1就是1 ^&#xff1a;相同为0&#xff0c;相异就是1/无进位相加 给定一个数n,确定它的二进制表示中的第x位是0还是1&#xff1a;二进制中权值最小的是第0位&#xff0c;所以int整型是从第0位到…

Android app Java层异常捕获方案

背景&#xff1a; 在Android app运行中&#xff0c;有时一些无关紧要的异常出现时希望App 不崩溃&#xff0c;能继续让用户操作&#xff0c;可以有效提升用户体验和增加业务价值。 新流程&#xff1a; 哪些场景需要Catch Crash Config配置信息&#xff1a; 支持从网络上获…

MySQL 5.7.42 主从复制环境搭建

MySQL 5.7.42 主从复制环境搭建 下载MySQL二进制包操作系统环境配置安装过程搭建从库 本次安装环境&#xff1a; OS版本&#xff1a;Red Hat Enterprise Linux Server release 6.8 (Santiago) MySQL版本&#xff1a;5.7.42 架构&#xff1a;同一台机器&#xff0c;多实例安装搭…

国标GB28181视频汇聚平台EasyCVR安防监控系统常见播放问题分析及解决方法

国标GB28181安防综合管理系统EasyCVR视频汇聚平台能在复杂的网络环境中&#xff0c;将前端设备统一集中接入与汇聚管理。平台支持多协议接入&#xff0c;包括&#xff1a;国标GB/T 28181协议、GA/T 1400协议、RTMP、RTSP/Onvif协议、海康Ehome、海康SDK、大华SDK、华为SDK、宇视…

【工具测评】ONLYOFFICE8.1版本桌面编辑器测评:好用!

随着远程工作的普及和数字化办公的发展&#xff0c;越来越多的人开始寻找功能强大、易于使用的办公软件。在这个背景下&#xff0c;ONLYOFFICE 8.1应运而生&#xff0c;成为许多用户的新选择。ONLYOFFICE 8.1是一款办公套件软件&#xff0c;提供文档处理、电子表格和幻灯片制作…

【node】深入探讨 class URL

【node】深入探讨 class URL &#x1f4cc; 浅说 fileURLToPath() 在vite.config.ts中有这么一段代码&#xff1a; import { fileURLToPath, URL } from node:url import { defineConfig } from vite export default defineConfig({resolve: {alias: {: fileURLToPath(new U…

python学习笔记四

1.自己平方本身 x2 x**4#xx**4 print(x) 2.把一个多位数拆分成单个数&#xff0c;方法一通过字符串下标获取对应元素&#xff0c;并对获取的元素使用eval函数把左右引号去掉&#xff0c;是字符串变为整型&#xff1b;方法二&#xff0c;通过对数进行取余和整除得到各个位的数 …

RK3568平台开发系列讲解(I2C篇)利用逻辑分析仪进行I2C总线的全面分析

🚀返回专栏总目录 文章目录 1. 基础协议1.1. 协议简介1.2. 物理信号1.3. 总线连接沉淀、分享、成长,让自己和他人都能有所收获!😄 1. 基础协议 1.1. 协议简介 IIC-BUS(Inter-IntegratedCircuit Bus)最早是由PHilip半导体(现在被NXP收购)于1982年开发。 主要是用来方…