Part 12 - Spawning things.

By Jamie Chatterton / 2018-06-12

Back to the script.

What do we want it to do?

Every X seconds, create a new instance of the ObjectToSpawn and add it to the scene at some arbitrary location.

So how do we do this?

Timing

Well. We have a function Update this is called every frame. If we keep track of time, after X seconds we could create a new object where we want, and then start counting again.

We have access to a global timer, called Time it has a number of different was of telling the time. The best one we have is Time.time, which is the number of seconds that have elapsed since the start of the game.

So roughly, linearly we have something like

while(true) {
  startTime = Time.time
  wait until Time.time - startTime >= X
  create a new instance
}

We can't do this linearly with our current toolset, so we have to do something like…

public class SpawnerController : MonoBehaviour {

	public GameObject ObjectToSpawn;

	private float startTime;

	// Use this for initialization
	void Start () {

		startTime = Time.time;

	}

	// Update is called once per frame
	void Update () {

		if (Time.time - startTime > 1.0f) {
			SpawnObject();
			startTime = Time.time;
		}

	}
}

So in Start we set the current time to the current game time.

In Update we are checking if the different in time is greater than our spawn time (1 second).

If it is, we call our SpawnObject function and then reset the time to the current time so it'll wait another second.

However, at present it won't compile… the SpawnObject function doesn't exist. How do we do that?

Spawning

Creating a new instance of an object is fairly simple.

The function is called Instantiate. Every GameObject has it in its super class definition somewhere. You can just call it to create a new object. If you pass in an existing GameObject it will create a copy of that object. Which is exactly what we need. We are going to pass it the "prefab" the ObjectToSpawn and it will copy that.

However, by default, new objects are just spawned into the root of the project. That'll get rather messy, rather quickly. To keep it fairly tidy whilst the number of objects increases, it's probably best to create the objects under the spawner object. To do this you pass the 'transform' of the GameObject you wish to be the parent of the new instance.

This form of the SpawnObject function will be

void SpawnObject() {
		Instantiate(ObjectToSpawn, transform);
	}

And is placed under the Update function in my code… not that it really matters.

Run it… oh… there's a problem.

The coins aren't appearing in the right place.

When instantiating, the object's "local" position is taken into account and added to the existing position of any parent it's attached to.

Because our 'coin' is not at (0,0,0) it won't be at the correct position and will be moved relative to the 'spawner' parent when it is added to it. Ultimately the best thing to do is edit the Prefab.

Clicking on the 'coin' prefab, edit the Transform Component in the Inspector and set the Position values all to 0. So it looks like

Open this image in a new tabEdited Transform Component
Edited Transform Component

Now run it.

It works much better.

This will now spawn objects forever.

Git repository: https://bitbucket.org/hiveit/unity-tutorial-coin/src/009_AddingSpawnScript/

More posts in this series.