Chapter 5: Number of Aliens maxes out at MaxOnScreen

Hi.

The game won’t produce more aliens than the maxAliensOnScreen because in the GameManager the aliensOnScreen is incremented with each new spawn, but is never reduced when aliens are killed.

I added a private int aliensGenerated = 0;

changed:
if (aliensPerSpawn > 0 && aliensOnScreen < totalAliens)

to:
if (aliensPerSpawn > 0 && aliensGenerated < totalAliens)

I also changed:
aliensOnScreen += 1;

to:
aliensGenerated += 1;

And I added:
aliensOnScreen = GameObject.FindGameObjectsWithTag (“Alien”).Length;

at the beginning of update.

I also figured out how to tag the alien prefab with Alien.

I have no idea if findgameobjectswithtag is inefficient, but the game doesn’t work as is and I didn’t see any fixes when I skimmed through the rest of the book.

I agree FindGameObjectsWithTag is a bit heavy for this issue.

Alternatively you could keep track of how many aliens have been killed. Your onScreen value then becomes generated - killed.

FindGameObjectsWithTag is a heavy to use in the Update() loop, but will probably work OK for a prototype/fun project. Best practise is not to use this method though.

I would handle this by simply counting up each time an alien is spawned, and counting a different counter each time one is killed. You can then simply subject the killed from the spawned number to work out how many are currently ‘active’. You can then limit the spawning method so that it only spawns if that calculated number is below maxAliensOnScreen.

Another method of keeping track of “active” aliens, is to maintain a List (collection) of the aliens (you could use a List). Everytime you spawn one, you call list.Add(alienGameObject) and when you kill one, you call list.Remove(alienGameObject) - before it is destroyed of course! (Note this is pseudocode - I’m not sure what the actual names of the variables are without looking back at the code)!

My main point of this post is to make the authors aware of this error in the book.

How do I keep track of spawns and deaths when they are handled in different files?

1 Like

Thanks!

You can make the variables (fields) public. Then get a reference to the MonoBehaviour with one variable, from the other.

For example with ScriptA and ScriptB, where ScriptA has a public int field called “spawns”, in ScriptB you could have field at the top:

public ScriptA scriptAReference;

Then in one of your ScriptA methods you could do:

Debug.Log(scriptAReference.spawns);

Using the editor, select the GameObject with ScriptB attached, then drag and drop the reference to ScriptA to the scriptAReference field in the inspector.

Alternatively, you can use the GetComponent method that every MonoBehaviour has and you can avoid making a public field to reference ScriptA:

So in ScriptBs Start method for example you could do:

var scriptAReference = GameObject.Find("TheNameOfTheGameObjectWithScriptAAttached").GetComponent<ScriptA>();
Debug.Log("The value is: " + scriptAReference);