Heya!
Trying to understand how can I spawn several objects in a 2d space, with a set distance from one another, but in a seemingly random placement. There are going to be dozens of these prefabs.
Last thing I want is them to get too close to each other, or too far, but above all: they cannot spawn one on top of another.
Example:
They are at random distances and random sizes, but none overlap.
Any help will be appreciated, thanks
You could try something like:
float distanceFactor = 2f;
GameObject SpawnCopyNearby()
{
Vector3 randomPosition = Random.onUnitSphere * distanceFactor;
GameObject instance = Instantiate(gameObject, gameObject.transform.position + randomPosition, Quaternion.identity) as GameObject;
return instance;
}
Basically you create a random position using Random.onUnitSphere that will give you a set distance away from the object you want to copy. But do note this example does not check if it overlaps with another object or is it too close. You’d have to implement that check yourself and assign a more suitable random position, but you get the idea Good luck!
Thanks, but the main issue I have is the actual collision/overlap check, could you help with that?
Hmm, then assume we have a List with all of our objects that we spawned so far. Before instantiating the object, we could verify that the position generated does not overlap with others.
GameObject TrySpawnObject(float minimumDistanceRequired)
{
Vector3 randomPosition = gameObject.transform + Random.onUnitSphere * distanceFactor;
List<Transform> allObjects = ... //we assume this exists
foreach (Transform t in allObjects)
{
if (Vector3.Distance(t.position, randomPosition) <= minimumDistanceRequired)
{
return null;
}
}
return Instantiate(gameObject, randomPosition, Quaternion.identity) as GameObject;
}
So when we call it could look something like this:
GameObject instance = null;
int bruteForceSafety = 0;
while (instance == null && bruteForceSafety < 1000)
{
instance = TrySpawnObject( 2f ); //we set here the minimum distance
bruteForceSafety++;
}
if (instance != null)
{
allObjects.Add(instance.transform);
}
Idea behind this awful looking script is to brute force your way to find a nice spot where the distance is perfect. If you can’t find one, bruteForceSafety var will exit the loop so you don’t lock up indefinitely.
Please note this distance check example was created in mind that all of your objects will have the same size. You could try using this code for now, but I suggest you attempt to find a better solution. Good luck!
Thanks a lot, will try this and let you know!
Tweaked it a bit and now works exactly as intended. Thanks a lot!