Hello everyone,
I am using list.Count to check if list is empty or null, in all over my game scripts. In editor it’s working exactly as expected. But in Windows standalone build, it’s throwing null reference exception error if list count is 0, even if list is already initialized. And now I am using list != null along with list.Count to get expected results. Why same code behaving differently in the Editor and in the Build?
What is the right way to check if a list is empty or null?
Count > 0
is the normal way to check so long as the list is initialised/isn’t null. Naturally if the list isn’t initialised you’ll get an error.
So you should be checking why your lists aren’t initialising as expected and work from there.
Thanks for the reply. As I already mentioned in the question list is already initialized without any doubt. It’s working great in the Editor but throwing error in the Standalonr build. Script Example:
List <GameObject> gos = new List<GameObject>();
if(isPlayer)
{
gos = EnemyAllyList.playerAllTargetsTmp;
}
else if(isFaction1)
{
gos = EnemyAllyList.faction1AllTargets;
}
else if(isFaction2)
{
gos = EnemyAllyList.faction2AllTargets;
}
else if(isPirate)
{
gos = EnemyAllyList.pirateAllTargets;
}
Vector3 diff;
float distance = Mathf.Infinity;
if(gos.Count != 0) // Error here
{
//Debug.Log("GOS Available");
mode = Mode.Attack;
}
Well in the above case, one of those methods could be returning a null list which will cause the error. list.Count
isn’t the issue here, it’s the fact that in some way shape or form your list is becoming null. That’s what you need to investigate here.
Actually my question title was wrong. Title should be “Why same code behaving differently in the Editor and in the Build”.
Do you know why?
Well, there are some differences between running code inside the editor and in a build version. Specifically when you “view” an object inside the inspector, the Unity editor will initialize arrays / Lists for you so they can be edited inside the inspector. However if you create such objects at runtime and you don’t have initialized those lists manually, they would be null.
We can’t tell you what’s wrong in your specific case since we don’t know how / where you initialize your 4 lists. You create a list in line 1 of the code snippet you posted, but this list is thrown away if any of the 4 if statements is true and the value in “gos” is replaced by whatever is in that list you assign inside your if statement. So as Spiney said, one of though is probably null. We can’t tell you which or why since, as just said, we don’t know if and how you initialize those lists.
Note that your approach is not a good one. You always create a new list which is most likely replaced by one of the 4 so that new list becomes garbage immediately. It would make more sense to add an else case at the end of your if-else chain and initialize your list only if none of the above cases apply. So just delcare the variable like this:
List <GameObject> gos;
and then have an else case like this:
gos = new List<GameObject>();
Just to make that clear: When you do gos = EnemyAllyList.playerAllTargetsTmp;
inside your if statement, the old value that was assigned to “gos” is thrown away and replaced by the list stored inside the “playerAllTargetsTmp” variable. If that variable does not contain a List instance but just null, you would set gos also to null.
Thank you so much for such detailed explanation :). One more question.
What is the best way to check if a list is not empty and null?
Currently I am using:
if(list != null && list.Count > 0)
{
}
Is there a better way?
Both are fine and will be your main ways to do so, though have different obvious use cases.
A common problem that people encounter when going fro editor to build is that the various GameObjects messages can resolve in a different order between the editor and a build/ For example, if you instantiate an object in the Start() of Object A and you reference that same object in the Start() of object B- that works fine as long as the Start() in A always runs before the Start() in object B. If the Start() of object B runs first, however, then you’ll get a null reference exception because you are trying to access the instance before it is instantiated. You can run this in the editor over and over again and Object A might always run first and you’ll never catch the error until you make a build.