Unity json反序列化为 字典存储

当在Unity游戏中需要加载和管理游戏数据,通常使用JSON文件是一种常见的方法。在本篇博客中,我们将深入探讨如何使用C#和Unity的JSON反序列化功能来实现这一目标。我们可以使用Unity的JsonUtility来反序列化JSON数据并将其映射到自定义的C#数据结构中。

首先,让我们来创建一些数据类,以便加载和管理游戏中的角色和武器数据。在这个示例中,我们将使用Player(角色)、Monster(怪物)和WeaponData(武器数据)这三种数据类型。

xml 复制代码
{
  "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序列化和反序列化

csharp 复制代码
[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文件示例是一个包含多个玩家信息的数组。

csharp 复制代码
[Serializable]
	public class PlayerData
	{
		public List<Player> players = new List<Player>();
	}

我们可以用一个玩家数据结构的数组去存储这个json文件,并

csharp 复制代码
TextAsset textAsset = Managers.Resource.Load<TextAsset>($"Data/PlayerData");
PlayerData []players JsonUtility.FromJson<Loader>(textAsset.text);

去解析并且遍历它放到字典里,

当我们要解析的json特别多时 我们定义了一个泛型方法LoadJson,该方法负责加载JSON数据并将其反序列化为具体类型的字典。这个方法接受一个Loader类型,该类型必须实现ILoader接口。

csharp 复制代码
 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接口

cpp 复制代码
public interface ILoader<Key, Value>
{
    Dictionary<Key, Value> MakeDict();
}

我们让存储具有JSON数据结构的数组继承该接口

csharp 复制代码
	[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文件反序列化放在数组中

csharp 复制代码
 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();
        
    }

代码如下

csharp 复制代码
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数据并将其转化为字典对象。

csharp 复制代码
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反序列化和数据管理有所帮助。如果你有任何问题或需要进一步的指导,请随时在评论中提问!

相关推荐
程序员霸哥哥4 小时前
卸载工具uninstall tool下载安装教程(附安装包)绿色版
windows·uninstall tool
Dolphin_Home10 小时前
轻量实用的 XML 与 JSON / 对象互转工具类(Jackson 实现)
xml·java·json
女程序猿!!!10 小时前
视频分辨率
windows
不讲废话的小白10 小时前
文件拖不进企微了怎么办
windows·企微
聪明努力的积极向上11 小时前
【.net framework】WINDOWS服务和控制台程序简单介绍
windows·.net
程序员霸哥哥15 小时前
snipaste免费版下载安装使用教程(附安装包)
windows·microsoft·snipaste
程序员霸哥哥16 小时前
Keil5下载教程及安装教程(附安装包)
windows·keil5·keil5下载教程·keil5安装教程
AI大模型学徒16 小时前
Chatbox 安装 for Windows
windows·语言模型·chatgpt
llxxyy卢17 小时前
json的注入
json
千里马学框架18 小时前
windows系统上aosp15上winscope离线html如何使用?
android·windows·html·framework·安卓窗口系统·winscope