Custom class list troubles :(.

Sorry for the vague title, it’s hard to explain in one sentence but it’s not complex either.

I have a custom class for items, with a few values like value and damage. I also have a list of some instances of these classes, acting as an inventory. Of course it’s possible that the lists contains multiple instances that have the same values (but should really be distinct items).

There could be two daggers with the same values and one sword with different values, for example.

Herein lies the problem: Wheniver I access one of the instances in the list to change, say, the damage, all other instances that share the same values get changed as well! Why? :frowning:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
 
 
public class test : MonoBehaviour {
 
	[System.Serializable]
	public class Item {
		public string name;
		public int value;
		public int damage;
	}
 
	public Item daggerTemplate = new Item { name = "Dagger", value = 10, damage = 20 };
	public Item swordTemplate = new Item { name = "Sword", value = 100, damage = 50 };
 
	public List inventory;
 
	void Start() {
 
		inventory = new List();
		Item item1 = daggerTemplate;
		item1.value = 2;//this causes all other daggers to change their value to 2 as well
		inventory.Add(item1);
 
		Item item2 = daggerTemplate;
		inventory.Add(item2);
 
		Item item3 = swordTemplate;
		blubbListinventory.Add(item3);
 
	}
}

can you show some code? it most likely has to do with the way you're storing and accessing them. but it's hard to say. are you using static variables? how are the classes instantiated? showing code is the best way here

All that share the "same values" or share the same reference type(the class)? If you're not instantiating a new object from your classes and you associate it in a collection, the reference will point to the same object in memory.

Maybe you are storing reference and the two daggers in fact are the same reference. We need the code to see how do you create it.

Sorry, I planned to post the code but first the formatting buttons disappeared and then the UA site slowed to a crawl. I have added it shortly after posting :)

2 Answers

2

You’re using the same instances, you need to instantiate a new object from your class:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
 
 
public class test : MonoBehaviour {
 
    [System.Serializable]
    public class Item {
        public string name;
        public int value;
        public int damage;
    }
 
    //public Item daggerTemplate = new Item { name = "Dagger", value = 10, damage = 20 };
    //public Item swordTemplate = new Item { name = "Sword", value = 100, damage = 50 };
 
    public List inventory;
 
    void Start() {
 
        inventory = new List();
        inventory.Add(new Item { name = "Dagger", value = 2, damage = 20 });
        inventory.Add(new Item { name = "Dagger", value = 10, damage = 20 });
        inventory.Add(new Item { name = "Sword", value = 100, damage = 50 });
 
    }
}

Oh well, I found a workaround where I would just store all fields from a source item(the item template, like a dagger) and then put those values into the target item. It requires “using System.Reflection;”

 public static Item CopyItemValues(Item sourceItem, Item targetItem) {
	FieldInfo[] sourceFields = sourceItem.GetType().GetFields(BindingFlags.Public | 
	                                              BindingFlags.NonPublic | 
	                                              BindingFlags.Instance);

	int i = 0;

	for(i = 0; i < sourceFields.Length; i++) {
		var value = sourceFields*.GetValue(sourceItem);*

_ sourceFields*.SetValue(targetItem, value);_
_
}_
_
return targetItem;_
_
}*_