- Home /
The question is answered, right answer was accepted
Trouble with fieldInfo.SetValue() and arrays
Hmmm... Again having trouble with SetValue... Well, since I didn't found anything about this in the web I've decided to ask it here:
I have this void, witch is:
public void AddItem(Collider2D other, int amount)
{
int[] itemArray = (int[])GetType().GetField(other.GetComponent<Drops>().ItemType.ToString(), BindingFlags.Public | BindingFlags.Instance).GetValue(this);
int id = other.GetComponent<Drops>().id;
if (itemArray.Length > id)
GetType().GetField(other.GetComponent<Drops>().ItemType.ToString()).SetValue(this, itemArray[id] + amount);
else Debug.LogWarning("Help here! Not working at all! " + other.GetComponent<Drops>().id);
}
It was supposed to detect two things when a player triggers with an item:
public enum ItemType {basicMaterial, advancedMaterials};
public class Drops : MonoBehaviour
{
int id; //If ItemType is equals to basicMaterial: 0 = Carbon, 1 = Copper...
}
My only problem is after that. Once it is done detecting those things, it needs to ADD, lets say one, to an array. How does it knows where to add it? Easy. Using:
GetType().GetField(Collider2D other.GetComponent<Drops>().ItemType.ToString());
I can easely find the array (since its name is equals to the ItemType (ex. array, ItemType: basicMaterials)), but I can't apply the value to it, sice I can't define at what point of the array's length I must add it. Any help would be amazing!
PS: After all that I still place that array inside another script, and then I save it to a .json file, but this I've already made and mastered.
I'm using fieldInfo.SetValue because I want my scripts to be as short as possible, and as readable as possible.
Another thing is that I call AddItem() inside of OnTriggerEnter2D() and set the Collider2D from AddItem() as the Collider2D from OnTriggerEnter2D().
Yes, I'm aware that I could just change the values individually for each array instead of trying to find it depending of witch ItemType is assigned and witch id is assigned, but I don't want my scripts to get overpopulated, so...
Answer by ShadyProductions · Jun 02, 2017 at 01:11 PM
You should use a list for this, but if you really want to go for an array.
I suppose you could do something cheap using LINQ like this:
var list = itemArray.ToList(); //convert array to a list
list.Add(youritem); //add the value
itemArray = list.ToArray(); //re-convert the list to an array
Actually, indexing an array's value to the "itemArray" isn't the problem. The problem is in how to add the value to the array that "itemArray" represents using "System.Reflection". To be honest with you, I never did fully understood the lists... Then I can't know if that could solve my issue.
By the way, how do I do something like this for a list?
itemArray[someLengthPoint];
Reflection is a bad thing to use because it is very performance taking, I really do not recommend using reflection. List's are the perfect solution to your problem. Use my linq statement it should work to what you are trying to achieve. It doesn't change an existing index, it add's a new index. To be honest, if each item has a certain ID, then I would just simply use a dictionary ins$$anonymous$$d of an array.
//not that the key is unique, so you can't have the same id
https://www.dotnetperls.com/dictionary
Dictionary<int, Item> itemDictionary = new Dictionary<int, Item>();
then you can do something like this
itemDictionary.Add(id, Item);
and to get a value by its Id:
Item itemValue;
if (itemDictionary.TryGetValue(id, out itemValue)) {
//it found the item and it is referenced inside the itemValue variable
}
else {
//it did not find your item by this id, and itemValue variable is null
}
Yeah, it kinda works, but still, how do I apply the "itemArray" to it's "parent" array? Just like I'm trying to do at line 7, inside AddItem(). (Still talking about the list thing, not the Dictionary one).