Spawning Objects Randomly in Unity

A tutorial to help you make games with enemies, coins and other trinkets moving all over the place, the more random the better to keep players always on the edge of danger and reward!

What’s a game without enemies, coins and other trinkets spawning everywhere, the more random the better to make your players always on the edge of danger and reward?

Our games need this! So, let’s learn how to make objects move and spawn randomly in this free tutorial.

The best way to learn is through example. We’re going to use a super basic 3D Whackamole game prototype to show you how to implement random movement.

In this tutorial:

To follow along, you’re going to need a Unity project open that has at least one object that we can write scripts for. If you need help setting up your Unity project, go to our post How to Build a Unity Virtual Reality Game.

We’re using Unity v5.4.3f1. If you’re using a different version of Unity and find an incompatibility, drop us a comment down below with your question. Also, we know this tutorial is long, so feel free to use the comments to bookmark your spot!

Step 1: Making A Game Controller

To make our moles appear from time to time, we need to make a game object that controls the rules of the game.

Open your Unity project. Create an empty game object. Name the object “GameController”. Give GameController the position 0 0 0.

Create a C# script named “GameController” in Assets. Drag and drop the script to the GameController object. Open the script.

The plan is for GameController to access all the moles. Eventually we’ll make a mole that will appear every few seconds. And we can even make the moles appear faster and faster as the game continues. Let’s do it.

But first, the GameController needs to understand the Mole container. Therefore, we need a reference to the Mole container.

In GameController.cs, declare the following variable at the top of the class. This variable, named moleContainer, will reference the Mole container.

Note that the variable type is GameObject. That means the value that the variable holds will be a game object.

public class GameController : MonoBehaviour {

public GameObject moleContainer;

// Use this for initialization
void Start () {

}

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

}
}

Step 2: Storing Objects

Next let’s declare an array to store all the moles.

Arrays are lists of items, typically variables. The array represents a group of items as one unit.

public GameObject moleContainer;
private Mole[] moles;

Next we need to connect the object in our Unity game with the game object we’ve created with C#. To do so, save the script, and open Unity. Drag and drop the MoleContainer object to the Mole Container field in Game Controller’s Script component. Thus we have a reference to MoleContainer.

Open GameController.cs. In the Start method, type the following code to store the child objects in MoleContainer in the moles variable.

// Use this for initialization
void Start () {
    moles = moleContainer.GetComponentsInChildren ();
}

To test whether the moles variable contains all the moles in the scene, include the following line of code, which will print the length of the moles array.

// Use this for initialization
void Start () {
    moles = moleContainer.GetComponentsInChildren ();
    Debug.Log (moles.Length);
}

Save the script, and open Unity. Press Play. The console will print “9” because there are nine moles in the scene. As such, we know we have a reference to all the moles in the scene.

storing objects in a container
Your console should print the number of objects stored in the container.

Step 3: Using Random.Range()

Let’s have a mole move up at random. Open Mole.cs. Above the OnHit method, create the Rise method.

public void Rise () {

}

Copy the code from OnHit, and paste it into Rise. Replace hiddenHeight with visibleHeight as follows:

public void Rise () {
targetPosition = new Vector3 (
      transform.localPosition.x,
      visibleHeight,
      transform.localPosition.z
    );
}

We’ll want to call the Rise method on a random mole. A random mole will appear for the user to whack. Save the script, and open GameController.cs. In the Start method, use the following code to access one random mole in the moles array.

// Use this for initialization
void Start () {
    moles = moleContainer.GetComponentsInChildren();

    moles[Random.Range(0, moles.Length)]
}

Random.Range will return a random number from 0 to 9, not including 9. Remember that each variable in the moles array has an index from 0 to 8, to differentiate the nine different moles in the array.

Then add the following code to call the Rise method on the random mole.

// Use this for initialization
void Start () {
    moles = moleContainer.GetComponentsInChildren();
    moles[Random.Range(0, moles.Length)].Rise ();
}

Save the script, and open Unity. Press Play. No mole will rise.

This occurs because we are making the mole rise in the Start method in GameController.cs. The Start method in Mole.cs makes the moles hide. Stop playing the scene.

Step 4: The Awake() Method

GameController.cs is called before Mole.cs, although sometimes the order is flipped. To set the moles to hide before GameController.cs is run, change the Start method in Mole.cs to Awake().

// Use this for initialization
void Awake () {
    targetPosition = new Vector3 (
      transform.localPosition.x,
      hiddenHeight,
      transform.localPosition.z
    );
    transform.localPosition = targetPosition;
}

Save the script, and open Unity. Press Play. One mole will be visible.

one mole visible
This is what our code produced!

Step 5: Setting Appear Duration

Let’s have the mole wait a bit of time before disappearing. To do so, stop playing the scene. Open Mole.cs. Declare the following variable, which sets the time that a mole should be on the screen before disappearing to 0.5 seconds.

public float visibleHeight = 0.2f;
public float hiddenHeight = -0.3f;
public float speed = 4f;
public float disappearDuration = 0.5f;

Add another variable to time the disappearance.

private Vector3 targetPosition;
private float disappearTimer = 0f;

In the Rise method, use the following code to set disappearTimer equal to disappearDuration when a mole is visible.

public void Rise () {
    targetPosition = new Vector3 (
      transform.localPosition.x,
      visibleHeight,
      transform.localPosition.z
    );
    disappearTimer = disappearDuration;
}

In the Update method, type the following code to have disappearTimer count down.

// Update is called once per frame
void Update () {
    disappearTimer -= Time.deltaTime;

    transform.localPosition = Vector3.Lerp(transform.localPosition,
      targetPosition, Time.deltaTime * speed);
}

When disappearTimer reaches 0, we want the mole to hide. Create the following if block, which will run code when disappearTimer reaches 0.

disappearTimer -= Time.deltaTime;
if (disappearTimer <= 0f) {

}

Rename the OnHit method Hide.

public void Hide () {
    targetPosition = new Vector3 (
      transform.localPosition.x,
      hiddenHeight,
      transform.localPosition.z
    );
}

Below the Hide method, create a new OnHit method. We are doing some refactoring so that we do not have to replicate code. Call the Hide method in OnHit.

public void OnHit () {
    Hide ();
}

In the Update method, when disappearTimer reaches 0, call the Hide method to hide the mole.

if (disappearTimer <= 0f) {
    Hide ();
}

Save the script, and open Unity. Press Play. A mole will appear and quickly hide.

Let’s have the moles stay on the screen longer. Stop playing the scene. Select Mole. In the Inspector, change the value of Disappear Duration to 1.25. Press Apply.

cube 3d graphic
Implementing random numbers

Step 6: Spawning Objects Randomly

Next let’s work on the logic to make a random mole appear every few seconds.

To spawn moles randomly, we need to add some variables to our Game Controller. Declare the following variables in GameController.cs.

  • A variable to hold the length of time between random spawns.
  • A variable to hold the minimum length of time between random spawns.
  • A variable to keep track of the current length of time between spawns.

public GameObject moleContainer;
public float spawnDuration = 1.5f;
public float minimumSpawnDuration = 0.5f;

private Mole[] moles;
private float spawnTimer = 0f;

In the Update method, use the following line of code to count down spawnTimer.

// Update is called once per frame
void Update () {
spawnTimer -= Time.deltaTime;
}

When the value of spawnTimer is 0, a mole should rise. To implement that, create the following if block. This if block will run code when spawnTimer is less than or equal to 0.

// Update is called once per frame
void Update () {
spawnTimer -= Time.deltaTime;
if (spawnTimer <= 0f) {

}
}

Cut the line in the Start method that selects a random mole from the moles array. Paste the line into the Update method’s if block.

// Update is called once per frame
void Update () {
spawnTimer -= Time.deltaTime;if (spawnTimer <= 0f) {
moles[Random.Range(0, moles.Length)].Rise ();
}
}

Set spawnTimer to equal spawnDuration. This sets spawnTimer to 1.5 seconds.

moles[Random.Range(0, moles.Length)].Rise ();|

spawnTimer = spawnDuration;

Step 7: Spawning Objects Increasingly Faster

We want spawnDuration to decrease each time spawning occurs. We want the moles to appear faster and faster. Declare the following variable, which will allow us to decrease the value of spawnDuration.

public GameObject moleContainer;
public float spawnDuration = 1.5f;
public float spawnDecrement = 0.1f;
public float minimumSpawnDuration = 0.5f;

In the Update method, before spawnTimer is set to spawnDuration, decrease the value of spawnDuration by spawnDecrement.

moles[Random.Range(0, moles.Length)].Rise ();

spawnDuration -= spawnDecrement;

spawnDuration begins at 1.5. It will decrease by 0.1 each time a mole rises. But, we don’t want spawnDuration to be smaller than minimumSpawnDuration. To account for this, create the following if block.

// Update is called once per frame
void Update () {
spawnTimer -= Time.deltaTime;
if (spawnTimer <= 0f) {
moles[Random.Range(0, moles.Length)].Rise ();

spawnDuration -= spawnDecrement;
if (spawnDuration < minimumSpawnDuration) {

}

spawnTimer = spawnDuration;
}
}

When spawnDuration is less than minimumSpawnDuration, set spawnDuration to equal minimumSpawnDuration. This ensures that the shortest interval between random spawns will be 0.5 seconds.

We have to set limits on the intervals, or else the intervals could be far too short or too long.

if (spawnDuration < minimumSpawnDuration) {
spawnDuration = minimumSpawnDuration;
}

Let’s test the script. Save the script, and open Unity. Press Play.

A mole will appear on the screen. will You be able to look at the mole and press Space to hide it. New moles will appear at an increasingly faster rate until the limit, appearing every 0.5 seconds.

moles spawning in unity
The moles will spawn faster and faster, until the maximum speed.

The game works! We did it. Don’t forget to save the scene.

We’ll continue this game in the next tutorial! Unless you oppose…. What tutorials do you want to see next? Drop a comment below.

Review

—Team Mammoth from Mammoth Interactive INC. Tutorial by Glauco Pires and Transcribing by Alexandra Kropova

Liked this tutorial? Get a free game development video course!

Leave a Reply

Your email address will not be published. Required fields are marked *