I'm making a game in Unity2D where are 4 roads that tanks drive on, tanks spawn in random positions, I want to make sure that a tank can't spawn in a position that another tank is already in. When I start the game the Unity Editor crashes I think there is a problem somewhere in the do while loop but I haven't found it, hoping I described it right. Thanks.
{
public GameObject tank;
public float spawnTime = 1f;
float positionX;
float positionY;
private bool check;
// Start is called before the first frame update
void Start()
{
InvokeRepeating("TankSpawn", 1f, spawnTime);
}
void TankSpawn()
{
do
{
int rndY = Random.Range(1, 5);
float rndX = Random.Range(20.5f, 35.0f);
if (rndY == 1)
{
positionY = -3.5f;
positionX = rndX;
}
else if (rndY == 2)
{
positionY = 0.5f;
positionX = rndX;
}
else if (rndY == 3)
{
positionY = 4.5f;
positionX = rndX;
}
else if (rndY == 4)
{
positionY = 8.5f;
positionX = rndX;
}
GameObject[] tanks = GameObject.FindGameObjectsWithTag("tank");
foreach (GameObject tank in tanks)
{
if (tank.transform.position.x == positionX && tank.transform.position.y == positionY)
{
check = false;
}
else
{
check = true;
}
}
} while (check != true);
Instantiate(tank, new Vector2(positionX, positionY), transform.rotation);
}
}```
CodePudding user response:
Firstly the problem that is doing you in:
By default bool variables. like check
, are false. The while loops when check
is false. The only way for check
to be set to true is thru the forloop if the generated coordinates don't match any tank positions. The problem with that is that if there are no tanks in the scene the forloop is never even started meaning that there is no way for check
to become true, ergo your while loop keeps looping and hangs up your editor.
A quick solution would be to check the length of found tanks array and if it is zero set check
to true.
if (tanks.Length == 0)
{
check = true;
}
Sidenotes:
- There is name ambiguity between the
tank
in the forloop and thetank
in the prefab. Its good practice to avoid that. - It is extremely hard to match two float values with
==
due to rounding. They might be extremely close, but are still different. - With your method tanks will still overlap. I would recommend to check if a position is truly free, by using Physics2D.OverlapBox or Physics2D.OverlapCircle
- If a lot of tanks spawn there might not be any valid positions. You should think of a way to timeout or impose some other limit, else you'll get softlocked in the while loop again.