- Home /
The question is answered, right answer was accepted
Null reference List in chest/crate problem.
I have a list that is public on a crate/chest that you can loot.
I don't know how to reference the empty spot in the list which stops the code from working properly if it isn't full.
Code:
for(int cnt = 0; cnt < crateItems.Count; cnt++){
// draw the item texture.
if(crateItems[cnt] == null){
// Draw the empty texture.
}
}
Again: I can't reference the empty slots, which also don't let the rest of code work as in unless the public list crateItems is filled with gameobjects the code won't show the other items in it.
Please assist thanks.
Is it throwing an error? If so, can you post it in a comment?
Also, what kind of objects does this crateItems container hold?
Yup it is. Its the error caused by not having all the slots filled. There are empty spots in the List. Which is what chest is supposed to be like.
Object reference not set to an instance of an object CrateUI.ONGUI()(at Assets/scripts/UI/CrateUI.cs:133)
Oh its just gameobjects with a Class and other scripts like for guns and such.
Its just stuff you use to kill people with mostly lol.
Ins$$anonymous$$d of leaving it null, populate it with a known quantity, like 0, if its an int array
Answer by ThePunisher · Nov 15, 2013 at 01:09 AM
You said you're using a list, right? I think you'll have to switch to an array, that way you can initialize all the slots as null then start populating what you need with actual references to objects. Then everything else should work the same way.
Edit: Actually, the empty slots would start off as null.
So it would look something like this
using UnityEngine;
public class Tasdf : MonoBehaviour
{
public GameObject[] objs = new GameObject[100];
private void OnGUI()
{
if (GUI.Button(new Rect(0, 0, 100, 50), "check"))
{
for(int i = 0; i < objs.Length; ++i)
{
if(objs[i] != null)
{
Debug.Log(objs[i].name);
}
else
{
Debug.Log("null");
}
}
}
}
}
Drag this onto an empty GameObject on an empty scene and hit the button. You will see null in the console window. Drag some objects to the inspector list and you'll see their names.
ALRIGHT. Thanks man.
I was about ask about the arrays.
Just one other thing though. How would I make sure only GameObjects with a certain class can be added. So as to avoid battle tanks being put into tiny boxes and such lol.
Oh ok wait never$$anonymous$$d I think I know. Because I'm using an automated system to put stuff into the crates. You know like random loot. But not in all crates. only in certain levels. I worry now it might start putting tanks and stuff in there.
A Dictionary List should do.
Well, you could make the array of the type of objects you want to allow ins$$anonymous$$d of GameObject. So, let's say that you had a base class for every item (like BaseItem), then you could make your array of BaseItem type and only GameObjects containing that script/class would be allowed.
Also worth pointing out that the thing that makes this work and not yours isn't that it's using an array. Since you were looping only to the end of the list, you'd never come across the case where you're overshooting the boundaries, so whether it's an array or a list makes no difference in this case (though arrays are more efficient if you can get away with a constant number of elements).
What makes this work is the order in which the code executes. Your code was trying to work in this way:
"Attempt to draw the texture. If that fails, draw the default texture."
While this one works in this way:
"Check if the object can be drawn. If it can, draw it, otherwise draw the default texture."
You can do either of these, but you need different notation for the first one. In many program$$anonymous$$g languages, when something is attempted but fails, it cancels the operation an throws an error. This is what was causing your code to not work - the error was aborting the operation before it ever got to the alternative path, because it wasn't defined as an alternative path. However, there is a way to stop errors from propagating, which is a way of saying: "I am expecting there to sometimes be an error here, but I will handle it myself." You can do this using a try{}catch(){}
block. These work like this:
try
{
//Code which might throw an Exception
}
catch(/*Class name of the exception*/) //In your case, this will be NullReferenceException
{
//Alternative code
}
This will work by first attempting the code in the try
segment. If this works, it will ignore the catch
segment and continue on. If the code in the try
block fails, however, it will throw an exception to the catch
block. If the exception that is thrown matches the execption specified in the catch
block, then it will stop the exception from going further, and execute the code in the catch
block ins$$anonymous$$d.
This is how you write code to run with the model you attempted. However, for this kind of error, it is much easier to just check if the object is null first, as ThePunisher did. These errors arise because you're trying to manipulate information from something that doesn't exist (it's a bit like telling someone to go and refuel a car when there is no car to refuel). It confuses the program if you try and do that, so a simple check first to make sure that there actually is an object (by testing if it is equal to null
) will prevent the error. By also adding an else
block, you can define alternative behaviour, too, as ThePunisher did.
I just wanted to expand on this, to explain what you did wrong, and why the solution given works. Hopefully you should understand a little more now.
Ah, did not realize that he was attempting to do something before checking for null. Silly me :p
Follow this Question
Related Questions
List the button didn't works 0 Answers
How to repeat the same list of buttons? 1 Answer
A node in a childnode? 1 Answer
How to make a or array of GUI.Button's? 1 Answer
gui text button dont work 1 Answer