- Home /
How to instantiate objects in a circle formation around a point?
Hello everyone, I would like to arrange some prefabs (eight to be more specific) in a circular formation around a center point, all equally spaced. They could be instantiated or just moved, I'm just trying to have them in circular formation. I've tried several supposed solutions from around the internet but each to no avail. What's the right thing to do?
Answer by Cornelis-de-Jager · Aug 29, 2019 at 10:04 PM
Explanation
If you don't really want to know just skip to final code snippet.
The circumferance of a circle is 2 * Pi * r
but we can ignore the radius in this case since we only want the spread around the circle, making the function 2 * Pi
. Lets say we have 5 enemies. This means each enemy must 2 * Pi / 5
distance around the circle (Radians) away from each other. We'll use num
to denote number of enemies making the formula: 2 * Pi / num
. If we were to loop through each enemy i
, the position of the current one around the circle would be the previous position plus 2 * Pi / num
. Meaning to determine the exact radians we can use 2 * Pi / num * i
.
for (int i = 0; i < num; i++){
/* Distance around the circle */
var radians = 2 * MathF.Pi / num * i;
...
}
We only have the radians now, but in unity we don't use radians so we need to convert radians into a direction (Vector3) and position (Vector3). To do that we need to fince both the vertcial and horizontal position. For vertical we can use Sin and horizontal we can use Cos. We can the add the new vector3 to the center point to get the spawn direction relative to center point and then multiply it by radius.
/* Get the vector direction */
var vertrical = MathF.Sin(radians);
var horizontal = MathF.Cos(radians);
var spawnDir = new Vector3 (horizontal, 0, vertcial);
/* Get the spawn position */ /* Get the spawn position */
var spawnPos = point + spawnDir * radius; // Radius is just the distance away from the point
Now that we have the spawn pos we can simply spawn the enemy, rotate it to look at the player and then adjust height so the enemies don't fall out of the world.
/* Now spawn */
var enemy = Instantiate (enemyPefab, spawnPos, Qaurtenion.Identity) as GameObject;
/* Rotate the enemy to face towards player */
enemy.transform.LookAt(point);
/* Adjust height */
enemy.transform.Translate (new Vector3 (0, enemy.transform.LocalScale.y / 2, 0));
Full Solution
This is how it will look like if we put it all together:
public GameObject enemyPefab;
public void CreateEnemiesAroundPoint (int num, Vector3 point, float radius){
for (int i = 0; i < num; i++){
/* Distance around the circle */
var radians = 2 * MathF.Pi / num * i;
/* Get the vector direction */
var vertrical = MathF.Sin(radians);
var horizontal = MathF.Cos(radians);
var spawnDir = new Vector3 (horizontal, 0, vertcial);
/* Get the spawn position */
var spawnPos = point + spawnDir * radius; // Radius is just the distance away from the point
/* Now spawn */
var enemy = Instantiate (enemyPefab, spawnPos, Qaurtenion.Identity) as GameObject;
/* Rotate the enemy to face towards player */
enemy.transform.LookAt(point);
/* Adjust height */
enemy.transform.Translate (new Vector3 (0, enemy.transform.LocalScale.y / 2, 0));
}
}
Hope this helpds. If you have any questions let me know.
Thank you so much for sharing this! I was doing this for UI, so using transform.SetParent and moving the vertical from the Z axis to the Y axis did the trick. Thanks again!
Thank you! now i'll try to find how to do this on a sphere :)
Answer by ssmas · Nov 06, 2021 at 06:54 AM
An easier way With normalizing the result you will get a point on circle diameter
Random.insideUnitCircle.normalized * radius;
Answer by metixgosu · Mar 20, 2021 at 08:22 PM
@Cornelis-de-Jager why dont you check your code before post answer , so many mystakes in it.
vertrical - vertcial .Mathf not MathF etc...
Answer by Riiich · Jan 24 at 12:40 PM
Here's @Cornelis-de-Jager's full solution answer but without the typos..
public void CreateEnemiesAroundPoint(int num, Vector3 point, float radius)
{
for (int i = 0; i < num; i++)
{
/* Distance around the circle */
var radians = 2 * Mathf.PI / num * i;
/* Get the vector direction */
var vertical = Mathf.Sin(radians);
var horizontal = Mathf.Cos(radians);
var spawnDir = new Vector3(horizontal, 0, vertical);
/* Get the spawn position */
var spawnPos = point + spawnDir * radius; // Radius is just the distance away from the point
/* Now spawn */
var enemy = Instantiate(enemyPefab, spawnPos, Quaternion.identity) as GameObject;
/* Rotate the enemy to face towards player */
enemy.transform.LookAt(point);
/* Adjust height */
enemy.transform.Translate(new Vector3(0, enemy.transform.localScale.y / 2, 0));
}
}
Answer by Rhoekin · Feb 14 at 12:46 PM
For anyone struggling with overlapping objects change
var radians = 2 * MathF.Pi / num * i;
To
var radians = i* 2 * MathF.Pi / num ;
This solves the division by 0 error, plus spaces the objects like theyre supposed to be placed
Your answer
Follow this Question
Related Questions
Move around a circle with iTween? 1 Answer
How can move the ball around the circle? 1 Answer
A way to create an invisible circle for the enemy? 4 Answers
How do i repeat the Lerp movement? 1 Answer
Hit problem unity 1 Answer