Unity json deserialization into dictionary storage

When it is necessary to load and manage game data in Unity games, using JSON files is a common method. In this blog, we’ll dive into how to achieve this using C# and Unity’s JSON deserialization capabilities. We can use Unity's JsonUtility to deserialize JSON data and map it into a custom C# data structure.

First, let's create some data classes to load and manage character and weapon data in the game. In this example, we will use three data types: Player, Monster, and 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"
    }
  ]
} 

We need to create a data structure that matches the JSON data. These classes use the [Serializable] attribute to enable JSON serialization and deserialization

[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;
	}`在这里插入代码片`

By observing the JSON file, we found that this JSON file example is an array containing multiple player information.

[Serializable]
	public class PlayerData
	{
    
    
		public List<Player> players = new List<Player>();
	}

We can use an array of player data structures to store this json file, and

use

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

To parse and traverse it and put it into the dictionary,
When we have a lot of json to parse, we define a generic method LoadJson, which is responsible for loading the JSON data and Deserialize to a dictionary of concrete types. This method accepts a Loader type, which must implement the ILoader interface.

 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 interface

public interface ILoader<Key, Value>
{
    
    
    Dictionary<Key, Value> MakeDict();
}

We let the array that stores the JSON data structure inherit this interface

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

This way you can deserialize the JSON file into an array

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

code show as below

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

}

In the Init method of DataManager, we load and initialize game data, including character data, weapon data and monster data. By calling the LoadJson generic method, we can easily load various types of JSON data and convert them into dictionary objects.

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

}

By using Unity's JsonUtility and C#'s generic methods, we can easily load and manage game data. This method is very useful for processing different types of data, and the code is highly reusable. I hope this blog will help you understand JSON deserialization and data management in Unity. If you have any questions or need further guidance, feel free to ask in the comments!

Guess you like

Origin blog.csdn.net/qq_45498613/article/details/134277057