Saturday, 20 June 2015

Auto Position Game Objects in Random Positions in Unity

I was working on a 2D game in Unity and I wanted a lot of game objects placed randomly in the level but I didn't want to spend a lot of time laying out each individual game object. I wanted to generate a lot of clouds in a level but without the hassle of manually laying them all out.

I achieved this by creating and attaching a script that would automatically layout the position of all the game objects in the level.


This is what an example of what the level looks like.

I created a C# script called GameObjectGenerator.cs.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

/***
 * Programatically generate a list of GameObjects at random positions 
 * between xOffset to xLength, yOffset to yLength and zOffset to zLength.
 */
public class GameObjectGenerator : MonoBehaviour {
 
 /***
  * The maximum number of objects to get generated
  */
 public int maxObjects = 10;

 /***
  * The type of game object to generate
  */
 public GameObject generatedObjectType;

 /***
  * The x-axis offset to position the game objects
  */
 public float xOffset = 0f;
 /***
  * The y-axis offset to position the game objects
  */
 public float yOffset = 0f;
 /***
  * The z-axis offset to position the game objects
  */
 public float zOffset = 0f;

 /***
  * The length of the level on the x-axis
  */
 public float xLength = 10f;
 /***
  * The length of the level on the y-axis
  */
 public float yLength = 10f;
 /***
  * The length of the level on the z-axis
  */
 public float zLength = 10f;

 /***
  * Internal list of all the generated game objects. 
  */
 private List gameObjects;

 void Start () {
  gameObjects = new List();
  generateGameObjects ();
 }
 
 public void generateGameObjects() {
  for (int i = 0; i < maxObjects; i++) {
   //get a random value between the offset and the length
   float xPos = Mathf.Clamp(xOffset + Random.value * xLength, xOffset, xLength);
   float yPos = Mathf.Clamp(yOffset + Random.value * yLength, yOffset, yLength);
   float zPos = Mathf.Clamp(zOffset + Random.value * zLength, zOffset, zLength);

   Vector3 position = new Vector3 (xPos, yPos, zPos);

   GameObject gameObject = (GameObject)Instantiate (generatedObjectType, position, Quaternion.identity);
   gameObjects.Add(gameObject);
  }
 }
}



First thing to do to get this working, is to create an empty game object and added it to the scene. I called it CloudGenerator. Attach the GameObjectGenerator script to the CloudGenerator. Once the script is attached, you can see all the parameters that can be changed for the script.

 
Description
Max Objects is the number of Game Objects that are going to be instantiated in the level.
Generated Object Type is the game object that is going to be generated throughout the level. In my case, it was a cloud sprite Game Object.
X Offset is the position on the X-Axis where the game objects will begin to get placed.
Y Offset is the position on the Y-Axis where the game objects will begin to get placed.
Z Offset is the position on the Z-Axis where the game objects will begin to get placed.
X Length is the length of the level in the X-Axis.
Y Length is the length of the level in the Y-Axis.
Z Length is the length of the level in the Z-Axis.

So from the example above, there will be 100 Cloud objects created in random positions from (-42, 4, -5) to (300, 7, 50).

This also brings parallax to the game since objects are created at random values on the Z-Axis. If you don't want parallax in your game, just set Z Offset and Z Length to 0.