Unity json反序列化为 字典存储
当在Unity游戏中需要加载和管理游戏数据,通常使用JSON文件是一种常见的方法。在本篇博客中,我们将深入探讨如何使用C#和Unity的JSON反序列化功能来实现这一目标。我们可以使用Unity的JsonUtility来反序列化JSON数据并将其映射到自定义的C#数据结构中。
首先,让我们来创建一些数据类,以便加载和管理游戏中的角色和武器数据。在这个示例中,我们将使用Player(角色)、Monster(怪物)和WeaponData(武器数据)这三种数据类型。
{"players": [{"id": "1","name": "player0","weaponID": "102","maxHp": "50","damage": "0","defense": "0","moveSpeed": "5.0","coolDown": "0","amount": "0"},{"id": "2","name": "player1","weaponID": "101","maxHp": "40","damage": "-10","defense": "0","moveSpeed": "5","coolDown": "20","amount": "0"},{"id": "3","name": "player2","weaponID": "101","maxHp": "50","damage": "20","defense": "1","moveSpeed": "5.0","coolDown": "-50","amount": "1"},{"id": "4","name": "player3","weaponID": "102","maxHp": "50","damage": "-50","defense": "-1","moveSpeed": "6","coolDown": "100","amount": "0"}]
}
我们需要创建了具有与JSON数据匹配的数据结构。这些类使用[Serializable]特性,以便能够进行JSON序列化和反序列化
[Serializable]public class Monster{public int id;public string name;public int maxHp;public int damage;public int defense;public float moveSpeed;public int expMul;}`在这里插入代码片`
通过观察JSON文件我们发现,这个JSON文件示例是一个包含多个玩家信息的数组。
[Serializable]public class PlayerData{public List<Player> players = new List<Player>();}
我们可以用一个玩家数据结构的数组去存储这个json文件,并
用
TextAsset textAsset = Managers.Resource.Load<TextAsset>($"Data/PlayerData");
PlayerData []players JsonUtility.FromJson<Loader>(textAsset.text);
去解析并且遍历它放到字典里,
当我们要解析的json特别多时 我们定义了一个泛型方法LoadJson,该方法负责加载JSON数据并将其反序列化为具体类型的字典。这个方法接受一个Loader类型,该类型必须实现ILoader接口。
Loader LoadJson<Loader, Key, Value>(string path) where Loader : ILoader<Key, Value>{TextAsset textAsset = Managers.Resource.Load<TextAsset>($"Data/{path}");return JsonUtility.FromJson<Loader>(textAsset.text);}
ILoader接口
public interface ILoader<Key, Value>
{Dictionary<Key, Value> MakeDict();
}
我们让存储具有JSON数据结构的数组继承该接口
[Serializable]public class PlayerData : ILoader<int, Player>{public List<Player> players = new List<Player>();public Dictionary<int, Player> MakeDict(){Dictionary<int, Player> dict = new Dictionary<int, Player>();foreach (Player player in players)dict.Add(player.id, player);return dict;}}
这样就可以将JSON文件反序列化放在数组中
public Dictionary<int, Data.WeaponData> WeaponData { get; private set; } = new Dictionary<int, Data.WeaponData>();public Dictionary<int, Data.Player> PlayerData { get; private set; } = new Dictionary<int, Data.Player>();public Dictionary<int, Data.Monster> MonsterData { get; private set; } = new Dictionary<int, Data.Monster>();public void Init(){PlayerData = LoadJson<Data.PlayerData, int, Data.Player>("PlayerData").MakeDict();WeaponData = LoadJson<Data.WeaponDataLoader, int, Data.WeaponData>("WeaponData").MakeDict();MonsterData = LoadJson<Data.MonsterData, int, Data.Monster>("MonsterData").MakeDict();}
代码如下
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public interface ILoader<Key, Value>
{Dictionary<Key, Value> MakeDict();
}public class DataManager
{public Dictionary<int, Data.WeaponData> WeaponData { get; private set; } = new Dictionary<int, Data.WeaponData>();public Dictionary<int, Data.Player> PlayerData { get; private set; } = new Dictionary<int, Data.Player>();public Dictionary<int, Data.Monster> MonsterData { get; private set; } = new Dictionary<int, Data.Monster>();public void Init(){PlayerData = LoadJson<Data.PlayerData, int, Data.Player>("PlayerData").MakeDict();WeaponData = LoadJson<Data.WeaponDataLoader, int, Data.WeaponData>("WeaponData").MakeDict();MonsterData = LoadJson<Data.MonsterData, int, Data.Monster>("MonsterData").MakeDict();}Loader LoadJson<Loader, Key, Value>(string path) where Loader : ILoader<Key, Value>{TextAsset textAsset = Managers.Resource.Load<TextAsset>($"Data/{path}");return JsonUtility.FromJson<Loader>(textAsset.text);}}
在DataManager的Init方法中,我们加载并初始化了游戏数据,包括角色数据、武器数据和怪物数据。通过调用LoadJson泛型方法,我们可以轻松地加载各种类型的JSON数据并将其转化为字典对象。
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;namespace Data
{#region Character[Serializable]public class Player{public int id;public string name;public int weaponID;public int maxHp;public int damage;public int defense;public float moveSpeed;public int coolDown;public int amount;}[Serializable]public class PlayerData : ILoader<int, Player>{public List<Player> players = new List<Player>();public Dictionary<int, Player> MakeDict(){Dictionary<int, Player> dict = new Dictionary<int, Player>();foreach (Player player in players)dict.Add(player.id, player);return dict;}}#endregion#region Monster[Serializable]public class Monster{public int id;public string name;public int maxHp;public int damage;public int defense;public float moveSpeed;public int expMul;}public class MonsterData : ILoader<int, Monster>{public List<Monster> monsters = new List<Monster>();public Dictionary<int, Monster> MakeDict(){Dictionary<int, Monster> dict = new Dictionary<int, Monster>();foreach (Monster monster in monsters)dict.Add(monster.id, monster);return dict;}}#endregion#region Weapon[Serializable]public class WeaponData{public int weaponID;public string weaponName;public List<WeaponLevelData> weaponLevelData = new List<WeaponLevelData>();}[Serializable]public class WeaponLevelData{public int level;public int damage;public float movSpeed;public float force;public float cooldown;public float size;public int penetrate;public int countPerCreate;}[Serializable]public class WeaponDataLoader : ILoader<int, WeaponData>{public List<WeaponData> weapons = new List<WeaponData>();public Dictionary<int, WeaponData> MakeDict(){Dictionary<int, WeaponData> dict = new Dictionary<int, WeaponData>();foreach (WeaponData weapon in weapons)dict.Add(weapon.weaponID, weapon);return dict;}}#endregion}
通过使用Unity的JsonUtility和C#的泛型方法,我们可以方便地加载和管理游戏数据。这种方法对于处理不同类型的数据非常有用,而且代码可复用性很高。希望这篇博客对你了解Unity中的JSON反序列化和数据管理有所帮助。如果你有任何问题或需要进一步的指导,请随时在评论中提问!
相关文章:
Unity json反序列化为 字典存储
当在Unity游戏中需要加载和管理游戏数据,通常使用JSON文件是一种常见的方法。在本篇博客中,我们将深入探讨如何使用C#和Unity的JSON反序列化功能来实现这一目标。我们可以使用Unity的JsonUtility来反序列化JSON数据并将其映射到自定义的C#数据结构中。 …...
助力青少年学习,亚马逊云科技2024年全球人工智能和机器学习奖学金计划正式启动
云未来将以何种方式发展?方向握在意气风发的少年们手中。近日,亚马逊云科技全球人工智能和机器学习(AI和ML)奖学金计划在中国区的首次颁奖以及2024年启动仪式在北京中学正式举行,有45名学子凭借杰出的学业成绩、对人工…...
华为机试练习题:HJ13 句子逆序
1、完整题目 HJ13 句子逆序 描述 将一个英文语句以单词为单位逆序排放。例如“I am a boy”,逆序排放后为“boy a am I” 所有单词之间用一个空格隔开,语句中除了英文字母外,不再包含其他字符 数据范围:输入的字符串长度满足…...
windows环境下安装Java过程(免登录Oracle官网下载java)
下载路径 oracle官网: java下载路径 Oracle共享账号可下载JDK: 指路 安装流程 执行下载后的jdk的可执行文件一路next下去, 可以自定义安装路径添加环境变量, 两个地方需要添加 在cmd中输入java -version 进行验证,…...
openssl交叉编译 (ubuntu+arm)
1.下载安装包 wget https://www.openssl.org/source/openssl-1.1.1w.tar.gz 2.解压安装包 tar -zxvf openssl-1.1.1l.tar.gz 3.进入源码文件夹-修改编译器 CCarm-linux-gnueabihf-gcc 4.配置编译参数 ./config no-asm -shared --prefix/home/alientek/sp_test/openssl/sp…...
Python 海龟绘图基础教学教案(十七)
Python 海龟绘图——第 34 题 题目:绘制下面的图形 解析: 使用循环绘制楼梯形。 答案: Python 海龟绘图——第 35 题 题目:绘制下面的图形 解析: 使用二重循环绘制四个方块。 答案:...
element ui多选框(Checkbox 多选框、Select多选框)编辑时无法选中的解决办法
1. Checkbox 多选框无法选中的解决办法: <!--v-model绑定的值必须是[],不能是字符串--><el-form-item label="配布对象" prop="reptGroupArray" > <!--多选--><el-checkbox-group v-model="form.reptGroupArray" size=&q…...
TCP/IP--七层通信
文章目录 TCP/IP--七层通信先来看一下会话层以上的处理再来看一下传输层以下的处理 TCP/IP–七层通信 下面举例说明7层网络模型的功能。假设使用主机A的用户A要给使用主机B的用户B发送一封电子邮件。 在七层OSI模型中,如何模块化通信传输? 先来看一下七…...
汽车标定技术(五)--基于模型开发如何生成完整的A2L文件(1)
1 数据对象的创建 CtrlH打开Model Explorer,在Base workspace中点击工具栏add,出现如下界面, 可以看到Simulink提供了多种数据类型 Matlab Variable:Simulink.Parameter:使用该数据对象表示工程应用中的标定量Simuli…...
重启某个节点、重启电脑服务器后,kubernetes无法运行,k8s无法运行
问题描述 环境:ubuntu18.04 LTS 现象:按步骤安装kubernetes后,正常启动,各个命令均可正常使用。服务器重启后,执行命令错误信息如下: sudo kubectl get nodesThe connection to the server 127.0.0.1:644…...
【ARMv8 SIMD和浮点指令编程】浮点加减乘除指令——四则运算
浮点指令有专门的加减乘除四则运算指令,比如 FADD、FSUB、FMUL、FDIV 等。 1 FADD (scalar) 浮点加法(标量)。该指令将两个源 SIMD&FP 寄存器的浮点值相加,并将结果写入目标 SIMD&FP 寄存器。 该指令可以产生浮点异常。根据 FPCR 中的设置,异常会导致在 FPSR 中…...
JDBC SQL Server Source Connector: 一览与实践
在快速发展的数据驱动业务环境中,确保数据在各个系统间高效、准确地同步至关重要。为了进一步的数据处理和分析,经常需要将这些数据同步到其他数据处理系统。Apache SeaTunnel 提供了一个强大而灵活的数据集成框架,使得从 SQL Server 到其他系…...
WebDAV之π-Disk派盘 + Keepass2Android
推荐一款密码管理器,允许人们使用复杂的组合进行登录,而不必记住所有的组合。 Keepass2Android可以支持大多数安卓互联网浏览器, Android设备上同步软件,还支持通过WebDAV添加葫芦儿派盘。 Keepass2Android 目前安全方面最大的问题之一是大多数人几乎在任何地方都使用通用…...
AspectJX - Android开发平台的AOP框架
官网 GitHub - HujiangTechnology/gradle_plugin_android_aspectjx: A Android gradle plugin that effects AspectJ on Android project and can hook methods in Kotlin, aar and jar file. 项目简介 一个基于AspectJ并在此基础上扩展出来可应用于Android开发平台的AOP框架…...
【TDK 电容 】介电质 代码 对应温度及变化率
JB 电解质是什么?没找到,只有TDK有,也只有这个温度的区别,并且已经停产在售。 对比发现是mouser网站关于电容的描述错误。下图显示正确的,再然后是错误的。 在TDK官网,这样的描述 温度特性 分类标准代码温…...
随笔--解决ubuntu虚拟环境的依赖问题
文章目录 问题一:在conda虚拟环境中报错ImportError: libcupti.so.11.7:cannot open shared object file: No such file or directory解决步骤问题二: RuntimeError: CUDA error: CUBLAS_STATUS_INVALID_VALUE when calling cublasSgemmStridedBatched( …...
Gin学习笔记
Gin学习笔记 Gin文档:https://pkg.go.dev/github.com/gin-gonic/gin 1、快速入门 1.1、安装Gin go get -u github.com/gin-gonic/gin1.2、main.go package mainimport ("github.com/gin-gonic/gin""net/http" )func main() {// 创建路由引…...
使用 OpenTracing 和 LightStep 监控无服务器功能
无服务器功能的采用在企业组织内达到了创纪录的水平。有趣的是,鉴于越来越多的采用和兴趣,许多监控解决方案孤立了在这些环境中执行的代码的性能,或者仅提供有关执行的基本指标。为了了解应用程序的性能,我想知道存在哪些瓶颈、时…...
Sleep(0)、Sleep(1)、SwitchToThread()
当 timeout 参数为 0 时(如 Sleep(0)),操作系统会检查可运行队列中是否有高于或等于当前线程优先级的其他就绪线程。如果有,当前线程将被移除并放弃处理器时间,让其他线程执行。如果没有高优先级的线程,当前…...
前端食堂技术周刊第 103 期:10 月登陆 Web 平台的新功能、TS 5.3 RC、React 2023 状态、高并发的哲学原理、Web 资源加载优先级
美味值:🌟🌟🌟🌟🌟 口味:夏梦玫珑 食堂技术周刊仓库地址:https://github.com/Geekhyt/weekly 大家好,我是童欧巴。欢迎来到前端食堂技术周刊,我们先来看下…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...
HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
