Hey everyone,
having some trouble with array elements returning data shown within inspector, below are a couple code examples. When using a loop function the code will return with data, however without the loop it returns an error. I’m just curious to why this is? Even though without the loop I can read / alter the data within the inspector, simply cannot access it via code.
ERROR : NullReferenceException: Object reference not set to an instance of an object
With Loop : Works
weaponCount = 3;
weapons = new WeaponData[weaponCount];
for(int i = 0; i < weaponCount; i++){
weapons [i] = new WeaponData ();
}
print(weapons[0]); //Returns with data
Without Loop : Doesn’t work…
Can see within inspector (something is there…)
weaponCount = 3;
weapons = new WeaponData[weaponCount];
print(weapons[0]); //Returns with Null
This is effectively the same as “print(null);”… Your array is empty and all elements are null until you insert instances into the array. The inspector is most likely allocating new instances of your WeaponData class during the serialization pass.
See, that’s where I’m confused…
I don’t understand how the array is empty without the loop although the inspector shows it has data. The WeaponData class is configured during Awake() and everything happens after that…also I’ve used a similar setup for a bunch of other sections within the code, it just seems to dislike this part for any reason
I mean I guess I can stick with the loop I was just hoping to slim the chunk down a little, it only runs once in a while so not a big deal, just annoying I suppose.
Awake() will be called if game object was instantiated, yours (in second code) were not. You have and array of empty spaces in memory suitable for those objects.
The serialization of the array in the inspector is most likely running the loop internally so it has instance data to display. If you want to slim down the code you can write an extension method and use that assuming your class is not derived from MonoBehaviour… You can extend the method further if you require constructor parameters but this will require usage of the Activator and reflection (or a FastActivator implementation which is probably out of the scope of this thread…).
NOTE Do NOT use the “new” keyword to create instances of MonoBehaviour objects.
Extension:
public static class ArrayExtensions
{
public static T[] Populate<T>(this T[] array) where T : new()
{
for (int i = 0; i < array.Length; ++i)
{
array[i] = new T();
}
return array;
}
}
Usage:
int weaponCount = 3;
WeaponData[] weapons = new WeaponData[weaponCount].Populate();
The only thing I can think of is that you never initialize any of the member variables. If you call new(), variables that have not been initialized (with null, or any other values), will be given some garbage. If you do initialize them with null, then you’ll have the problem you’re having. I’m not sure how your class would work given you’re using materials, and I’ve hardly worked with materials. But just make sure that you initialize the variables in your class
The issue is that the array has not fully formed when you call the print statement.
For an experiment, put that print statement into the Update Function, and see what happens.
This is why the loop works, but just the assignment does not.
With the loop, you are actually going through, and making sure each element has a value before you reach the print statement.
While with the assignment, Unity creates the array, and lets the array deal with element population while the script moves onto the next line, but the array has not finished populating when you attempt to access it on the very next line.
If you defined WeaponData as a struct, the second method would work too. Just know that you can’t and neither need to use “new” for structs. That makes the type similar to “int”, as in whole space is reserved and usable the moment its memory is created. Class instance is a pointer.
That said, structs are situational and i wouldn’t prefer to use them much.
Thanks everyone for putting up your suggestions, I’ll give them all a shot, this here sounds like what’s going on though…hoping it works. Script is starting to get crazy long, n in my experience less is better haha