• 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"
        }
      ]
    } 
    
    • 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
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    我们需要创建了具有与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;
    	}`在这里插入代码片`
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    通过观察JSON文件我们发现,这个JSON文件示例是一个包含多个玩家信息的数组。

    [Serializable]
    	public class PlayerData
    	{
    		public List<Player> players = new List<Player>();
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5

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

    TextAsset textAsset = Managers.Resource.Load<TextAsset>($"Data/PlayerData");
    PlayerData []players JsonUtility.FromJson<Loader>(textAsset.text);
    
    • 1
    • 2

    去解析并且遍历它放到字典里,
    当我们要解析的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);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    ILoader接口

    public interface ILoader<Key, Value>
    {
        Dictionary<Key, Value> MakeDict();
    }
    
    • 1
    • 2
    • 3
    • 4

    我们让存储具有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;
    		}
    	}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    这样就可以将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();
            
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    代码如下

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

    在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
    
    }
    
    • 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
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106

    通过使用Unity的JsonUtility和C#的泛型方法,我们可以方便地加载和管理游戏数据。这种方法对于处理不同类型的数据非常有用,而且代码可复用性很高。希望这篇博客对你了解Unity中的JSON反序列化和数据管理有所帮助。如果你有任何问题或需要进一步的指导,请随时在评论中提问!

  • 相关阅读:
    文心一言 VS 讯飞星火 VS chatgpt (99)-- 算法导论9.3 5题
    详解欧拉计划第227题:追赶游戏
    docker基础命令
    新的“HTTP/2 Rapid Reset”0day攻击打破了DDoS记录
    深度剖析倍增算法求解最近公共祖先(LCA)的细枝末节
    swagger动态开关实践
    深度模型中的优化(三)、梯度下降及其优化
    尚硅谷Flink(四)处理函数
    18 Linux之Python定制篇-Python开发平台Ubuntu
    北大肖臻老师《区块链技术与应用》系列课程学习笔记[20]以太坊-智能合约-1
  • 原文地址:https://blog.csdn.net/qq_45498613/article/details/134277057