- Home /
Preventing gameobjects from being spawned too close to each other
I just started playing around with unity but I'm having trouble figuring out how to prevent some gameobjects I want to spawn from spawning too close to each other. My code looks like this so far:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class WorldMapPoints : MonoBehaviour {
public GameObject waypoint;
public int waypointNumber = 50;
public int minimumYAllowed = 10;
public int minimumXAllowed = 10;
private List <Vector3> waypointPositions = new List<Vector3>();
int randomPositionX;
int randomPositionY;
void fillList(){
for (int i=0;i<=waypointNumber;i++){
waypointPositions.Add(new Vector3(randomPositionX, randomPositionY,0f));
randomPositionX =Random.Range(-300,300);
randomPositionY =Random.Range(-300,300);
Instantiate(waypoint, new Vector3(randomPositionX, randomPositionY,0f),Quaternion.identity);
}
}
void Start(){
randomPositionX =Random.Range(-300,300);
randomPositionY =Random.Range(-300,300);
fillList ();
}
}
I'm 100% certain this code looks horrible and it definitely doesn't do what I want it to do. I can't figure out how to check if the location of the waypoint spawned is too close to any waypoint spawned previously.
Answer by cjdev · May 15, 2015 at 08:36 AM
You could try something like this:
public GameObject waypoint;
public int waypointNumber = 10;
public float minDistance = 10f; // Each waypoint must be radius 10 apart
private List<Vector3> waypointPositions = new List<Vector3>();
void Start () {
FillList();
}
void FillList()
{
for (int i = 0; i < waypointNumber; i++)
{
for (int j = 0; j < 50; j++ ) // Gets a new random position until a valid one is found, ideally runs once
{
Vector3 randomPosition = new Vector3(Random.Range(-300, 300), Random.Range(-300, 300), 0);
bool close = false;
foreach (Vector3 wp in waypointPositions) // foreach loop cycles through each type (Vector3) in the list and names it (wp)
{
if (Vector3.Distance(wp, randomPosition) < minDistance) close = true; // Compares the distance between the random point and each existing waypoint
}
if (!close) // If the new point is valid add it to the list, instantiate it, and break out of the j-indexed for loop
{
waypointPositions.Add(randomPosition);
Instantiate(waypoint, randomPosition, Quaternion.identity);
break;
}
}
}
}
Basically it just uses Vector3.Distance to compare the new random vector with your list of existing vectors. The for loop with the j-index runs up to 50 times in case the random vector is too close and a new position needs to be calculated. For the distances you have it isn't likely to have to run more than a couple times, but it's generally better to have a finite loop rather than a while(true) loop with no breaking variable. I'm sure there are other ways to do it, that's what's great about programming, but I doubt you would get any performance gains from it.
What if we have a list of spawn points rather than a field with a range?
Answer by Lunar Soul · May 15, 2015 at 08:27 AM
I think the simplest way to execute this is to: Set an int named Previousx and PreviousY. So once you set the watpointPositions in void fillList(), you need to set PreviouX = randomPositionX and PreviousY = randomPostionY BEFORE you set the new random positions. Now you will need to do is make sure your new random positions are greater than or less than a certain distance of the previous x and y's.
I hope i helped.