Question about Global vs. Local Lists

Hi all,

I just figured out a bug, but I really don’t understand how/why it works the way it does. In the WaveConfig script of the Laser Defender course, I have the GetWayPoints method that gets the waypoints of my path. In the following buggy code, the waypoints list variable is declared as a global variable. What happened was that every time I ran my game, the waypoints were added to the list, i.e. the list went from a count of 0 to a count of 3 (expected). However, when I stopped my program and ran it again, it added another 3 to make a total count of 6 (not expected). Then another 3, then another. By the time I figured out what it was doing (I realized my enemies weren’t destroying as expected), I had over 1000 items in the list. My understanding is that it was somehow holding the contents of the list in memory in between runs. Is that correct? If so, then why?

private List<Transform> _waveWayPoints;

public List<Transform> GetWayPoints()
{
    foreach (Transform child in _pathPrefab.transform)
    {
        _waveWayPoints.Add(child);
    }
    Debug.Log("WaveWayPoints List has this many items: " + _waveWayPoints.Count);
    return _waveWayPoints;
}

Here is the code that now works as expected. Here I got rid of the global variable and instead declared and initialized the list as a local variable within the method. Again, I’m not sure why this works, other than the fact that local variables have restricted access. If anyone could explain this to me, I’d really appreciate it :D. Thanks!

public List<Transform> GetWayPoints()
{
    List<Transform> _waveWayPoints = new List<Transform>();
    foreach (Transform child in _pathPrefab.transform)
    {
        _waveWayPoints.Add(child);
    }
    Debug.Log("WaveWayPoints List has this many items: " + _waveWayPoints.Count);
    return _waveWayPoints;
}

Hi Jackie,

What you described sounds as if the List object still existed in memory. However, when you stop the game, that object should actually get destroyed and should not persist in memory. Since I don’t know what you you did exactly, I’m more surprised that you didn’t get any NullReferenceException in your “buggy” example.

In the second example, you create a new List object via new List<Transform>() inside the GetWayPoints method. I’m sure this would have worked with the first example as well.

Hi Nina,

So, if I’m understanding correctly, you are saying that both of the examples should have worked? i.e. using the list either globally or locally?

I did not receive any null reference errors with the first example, just the ever-expanding list of objects. The only change that I made that allowed the code to work as expected was moving the variable from global to within the method.

What exactly do you mean by globally? In C#, the term “global” usually refers to public static.

Did you stop the game in Unity by pressing the stop button or what were you doing?

private List<Transform> _waveWayPoints;

public List<Transform> GetWayPoints()
{
    _waveWayPoints = new List<Transform>();

    // rest of your code
}

This should have “worked” meaning “the” list would not become larger and larger because each time the GetWayPoints method gets called, a new List object gets created and assigned to _waveWayPoints.

By global, I meant that the variable was declared above everything else so that it can be used by all the methods in the script. I guess I’m using the terminology incorrectly. I tested the game with the play button and stopped it with the stop button every time.

The code you referenced isn’t one of the versions of code I tried. The one that I tried that worked is the second piece of code in my original post, where I both declared and defined the variable within the method. When I declared the variable outside of the method, that’s when the list kept growing.

That’s called a field or instance variable or member variable. :slight_smile:

As aforementioned, when you stop the game by clicking on the Stop button, the object is supposed to get destroyed. The list could grow, though, if GetWayPoints of one object gets called multiple times. You could check that with a Debug.Log and GetInstanceID().

1 Like

Hi, Nina! Thanks for your new vocabulary insight and troubleshooting techniques. I’ll play around with it. As I said, the issue is actually resolved, I just thought there may be a simple explanation for the behavior that I was seeing. Anyways, onwards and upwards! :slight_smile:

Sorry, I must have missed that part. Could you please mark the corresponding answer as the “Solution”? I thought you still wanted to know why one version didn’t work.

Learning the technical terms is very helpful because it’ll make it easier for you to find information on the internet and to communicate technical problems. :slight_smile:


See also:

Hi Nina,

Sorry for any confusion. The original post contains the solution that I am using, i.e. putting the variable within the method.

public List GetWayPoints()
{
List _waveWayPoints = new List();
foreach (Transform child in _pathPrefab.transform)
{
_waveWayPoints.Add(child);
}
Debug.Log("WaveWayPoints List has this many items: " + _waveWayPoints.Count);
return _waveWayPoints;
}

I did want to know why the other method didn’t work. I assumed I was missing something basic, but it seems that the source of the problem is not basic at all. I’m just going to go with the functioning solution and not dig too deep into this, as I am still at the very early stages of learning. I’ll mark this explanation as the solution so the ticket can be closed. Thanks for your help.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms