# Spawning next object not in line with the first object - 2D

Hello,

So I’m spawning one car each second. The problem is I’m using a random X range and sometimes multiple cars spawn around the same X position. So now I want to make it so the next car spawns at least 1 inch away from the first object.

Here is my current code:

``````Vector3 carPos = new Vector3(Random.Range(-maxPos, maxPos), transform.position.y, transform.position.z);

carNo = Random.Range(0, 7);

Instantiate(cars[carNo], carPos, transform.rotation);

carTimer = delayCarTimer;
``````

I know I can get the X spawning position by Debug.Log(carPos.x). The problem is the same value changes if the next car is spawned Can’t figure it out.

Use an Array to store the position, and then loop through the array each time to check that your random position isn’t close to something already used. It might be easiest round your x position to your desired precision, and then store an Array or List of ints. For example, if you want to check +/- 0.01 unit, then multiply your position by 100, then round to an int (e.g. everything between 1.145 and 1.154 becomes 115).

``````using System.Collections.Generic;

List<int> xPositions = new List<int>(); // stores the (rounded) previoously spawned x positions
public float checkDist; // x position distance to check

float carPosX;

// this is your spawning loop
bool flag = false;
while (!flag)
{
carPosX = Random.Range(-maxPos, maxPos); // generate random x value between min and max
int checkX = Mathf.Round(carPosX * (1 / checkDist)); // round using checkDist as precision
if (!xPositions.Contains(checkX)) // if the value doesn't exist in the List
{
flag = true; // exit the while loop
}
}

// then you can Instantiate knowing that your carPosX hasn't already been close to an already spawned value
``````

Note, I am not if front of Unity, so this code may have errors.

1 Like

Thanks for the answer. First I tried to store in a list and only change the position of the cars if the position was in the list already. But because 1.4 was stored as 1 and 1.6 was stored as 2 I had some troubles, the cars were still in line. So I choosed to change the position everytime. Here is the code I used probably not the most efficient way to do, but it works…

``````bool flag = false;
while (!flag)
{
//Get last position of the list
int number = xPositions.Count;
int lastItem = xPositions[number - 1];

if (lastItem <= 0)
{
spawnOnRightSide = true;
}

if (lastItem > 0)
{
spawnOnLeftSide = true;
}

//Not spawning between a range of +-1 of the last car position
notSpawnPositionMin = (lastItem) - 1f;
notSpawnPositionMax = (lastItem) + 1f;

//Spawn positions for the next car
newMinPosition = Random.Range(-maxPos, notSpawnPositionMin);
newMaxPosition = Random.Range(notSpawnPositionMax, maxPos);

//Round to int so we can add the new car position to the list
int checkXAgainRight = Mathf.RoundToInt(newMaxPosition);
int checkXAgainLeft = Mathf.RoundToInt(newMinPosition);

if (spawnOnRightSide == true)
{
}

if (spawnOnLeftSide == true)
{
}

flag = true;

carPosNotOk = true;
}

if (carPosNotOk == true)
{
if (spawnOnLeftSide == true)
{
Vector3 NewCarPos = new Vector3(newMinPosition, transform.position.y, transform.position.z); //Positie van het spawnen

carNo = Random.Range(0, 7);

Instantiate(cars[carNo], NewCarPos, transform.rotation); //We use the position and rotation of the CarSpawnPosition (empty gameobject)

carTimer = delayCarTimer; //We zetten de timer terug naar zijn startvalue, welke een is

randomSpawnNo = Random.Range(0, 8);

carPosNotOk = false;

spawnOnLeftSide = false;

if (randomSpawnNo == 5)
{
SpawnTwoCars = true;
}
}

if (spawnOnRightSide == true)
{
Vector3 NewCarPos = new Vector3(newMaxPosition, transform.position.y, transform.position.z); //Positie van het spawnen

carNo = Random.Range(0, 7);

Instantiate(cars[carNo], NewCarPos, transform.rotation); //We use the position and rotation of the CarSpawnPosition (empty gameobject)

carTimer = delayCarTimer; //We zetten de timer terug naar zijn startvalue, welke een is

randomSpawnNo = Random.Range(0, 8);

carPosNotOk = false;

spawnOnRightSide = false;

if (randomSpawnNo == 5)
{
SpawnTwoCars = true;
}
}
}
``````

I’m currently using a list which I’m not clearing during the game. Can this make the game laggy?

How many cars at maximum can spawn colliding with each other in case you don’t set an exception?
If only 2, you just need to set an old position which changes value every time a new car is spawned. I can write to you an example later on if that is the case.

I don’t really get what u mean. The cars spawn one at a time with a distance of 0.6-1 second between the cars.

Let’s say you are spawning the cars randomly, is it possible for more than two cars to overlap (spawn on top of each other) or at max you can get two cars overlapping

And if you do want to use the list, you’ll need to multiply your position by 1/precision where precision is the decimal precision you want to keep track of. For example:

``````float precision = 0.1; // used so 1.4 is stored as 14, 1.5 is stored as 15, etc.
// car transform is at 1.413
int lastPos = Mathf.Round(mycar.transform.x * (1 / precision));
// 1.413 * (1 / 0.10) = 14.13
// Mathf.Round (14.13) = 14
``````

This is what i am using for my game.

``````float xPos = Random.Range(screen_xmin, screen_xmax);   //Position bounded to screen width

// No new object should be within -0.6 to 0.6 of the object created before ( in my case, 1f is the width of the object )
//If the new object overlaps with the old one, give it new coordinates
while (xPos <= oldPos.x + 0.6f && xPos>= oldPos.x - 0.6f)
{
xPos = Random.Range(screen_xmin, screen_xmax);
}
oldPos.x = xPos;
``````

I tried this before but I had some problems with that. If 14 is stored in the list and the next car spawns at 15 they are spawning way too close.

Oh yes this would also work probably more efficient Are you also using a list to store the old positions?

I don’t need to because using the spawn rate that I’m using in my game, only two objects at max can collide. It all depends how many objects can spawn and collide at the same time on the related axis. But of course if the objects are many you have to use a list for old positions as you suggested.

Ok thanks for explaining.