Enemy stats are shared with all prefabs when getting stats from a JSON file

I have a character JSON file which contains the below enemy object.

{
		"name": "Enemy",
		"stats": [
			{
				"name": "Power",
				"Level": 3
			},
			{
				"name": "Health",
				"Level": 10
			}
		]
	}

I use the below to build the character database.
I originally saved the database in a static instance variable but now placed the CharacterDatabase script in the inspector on a game object instead.

 //public static CharacterDatabase instance { get; set; } // Originally tried with static instance
  private List<Character> characters { get; set; } // Now using a private variable
    
 characters = JsonConvert.DeserializeObject<List<Character>>(Resources.Load<TextAsset>("JSON/characters").ToString());

My Enemy prefab looks up their enemy stats by looking up it’s Prefab name in the character database. For example a prefab with the name Enemy would match the Enemy object above.


I am planning on using my prefabs in multiple places and am running into an issue of the prefabs sharing the same damage. The enemy I attack dies when their health reaches 0. The other enemy also has 0 health but dies when I attack that prefab instance after the other enemy died.


I made a copy of the Enemy object and changed it’s name to Enemy2. I renamed my second prefab to Enemy2 as well. When I did that, damaging each enemy worked correctly. So I am pretty sure that my issue happens because I am using a JSON file and connecting multiple prefabs to the same object causing them to share the stats instance.


Is there anyway I could create a separate copy of the stats so the prefabs do not share damage? Or should I try a different method for keeping track of character stats? I am pretty new to C# and Unity so I might be missing something obvious.

Found a solution to my problem. Will provide additional information and classes in my answers to help others understand my solution. The classes just show the relevant information.


Character class with list of Stats from CharacterBaseStat class

public class Character {
    public string Name { get; set; }
    public List<CharacterBaseStat> Stats { get; set; }
}

The CharacterBaseStat contains a method called Clone which uses MemberwiseClone. This helps in creating a separate copy of the stats for a character.

public class CharacterBaseStat
{
    public CharacterBaseStat Clone()
    {
        return (CharacterBaseStat)this.MemberwiseClone();
    }
}

The CharacterStats has the InstantiateCharacterStats method which is called from within an enemy or player class. It returns the character with a cloned CharacterBaseStat list.
The Clone method loops through all the character stats and creates a clone of each stat using CharacterBaseStat.Clone()

  public class CharacterStats : MonoBehaviour
    {
        private CharacterDatabase characterDatabase;
        public Character character;
        public List<CharacterBaseStat> characterStats;
        // Start is called before the first frame update
        void Start()
        {
            if (characterDatabase == null)
            {
                characterDatabase = CharacterDatabase.instance;
            }
        }
    
        public Character InstantiateCharacterStats(string characterName)
        {
            character = characterDatabase.GetCharacterByName(characterName);
            characterStats = Clone(character.Stats);
            return new Character(character.Name, characterStats);
        }
    
        private List<CharacterBaseStat> Clone(List<CharacterBaseStat> charStats)
        {
            List<CharacterBaseStat> newCharacterBaseStat = new List<CharacterBaseStat>();
            charStats.ForEach((stat) => newCharacterBaseStat.Add(stat.Clone()));
            return newCharacterBaseStat;
        }
    }