- Home /
place 8 objects around a target gameObject in a circle ( like a compass )
Hey there !
I'm trying to instantiate 8 different gameobjects around my character, but I don't really know the math behind it, to do it with Sin or Asin.
First I was trying to do a for cycle from 1-8, then tried to convert i to degrees then that back to vectors, but somewhere around I gave up on that try.
for (int i = 1; i < 8; i++) {
//Got the degree
float degree = Mathf.Asin(i / 360.0f);
//How to convert it to a vector ?
Vector2 vector = ?;
//Instantiating
Vector3 newPos = new Vector3(vector.x, y, vector.z);
GameObject go = Instantiate(GameObject.CreatePrimitive(PrimitiveType.Cube), newPos, Quaternion.identity);
}
Does anyone know the math behind it ?
Answer by Bunny83 · Sep 18, 2015 at 10:53 AM
float radius = 1f;
for (int i = 0; i < 8; i++)
{
float angle = i * Mathf.PI*2f / 8;
Vector3 newPos = new Vector3(Mathf.Cos(angle)*radius, y, Mathf.Sin(angle)*radius);
GameObject go = Instantiate(GameObject.CreatePrimitive(PrimitiveType.Cube), newPos, Quaternion.identity);
}
First of all all trigonometry functions work with radians and not degree (full circle is 2*PI). Second ASin only covers 180°. Next thing is you started your loop with "1" but ended it on "7" ( "< 8"). That's why you usually start at 0 and go up to 7 which are 8 values.
So all you need is Sin and Cos with equally spaced angles in radians.
A very late thank you for this. Easily adapted to arbitrary numbers of objects, and the results are pretty cool on a variable squad of NavAgents for target position offsets. :)
Answer by elButterfingers · Oct 18, 2019 at 06:03 PM
im a bit late for this but for anyone struggling with this @Bunny83 pretty much gave me everything i needed but i wrapped it into a pretty function for any amount of objects and from any position in the world.
public void instantiateInCircle(GameObject obj, Vector3 location, int howMany)
{
for (int i = 0; i < howMany; i++)
{
float radius = howMany;
float angle = i * Mathf.PI * 2f / radius;
Vector3 newPos = transform.position + (new Vector3(Mathf.Cos(angle) * radius, -2, Mathf.Sin(angle) * radius));
Instantiate(obj, newPos, Quaternion.Euler(0, 0, 0));
}
}
full credit to @Bunny83 , math is not my thing. neither is programming hence why i came here in the first place LOL.
The parameter 'location' is never used. Did you perhaps mean to replace 'transform.position' with it?
Answer by Raikish · May 06, 2020 at 11:19 AM
I Extended a little bit more the implementation of @elButterfingers and @Bunny83 , I added some methods for and parameters to customize better the usages. I hope that be useful! Cheers!
public class TestCreateObjectsInCircle : MonoBehaviour
{
public GameObject prefabToInstantiate;
/// <summary>
/// Instantiates prefabs around center splited equality.
/// The number of times indicated in <see cref="howMany" /> var is
/// the number of parts will be the circle cuted, with taking as a center the location,
/// and adding radius from it
/// </summary>
/// <param name="prefab">The object it will be intantiated</param>
/// <param name="location">The center point of the circle</param>
/// <param name="howMany">The number of parts the circle will be cut</param>
/// <param name="radius">
/// The margin from center, if your center is at (1,1,1) and your radius is 3
/// your final position can be (4,1,1) for example
/// </param>
/// <param name="yPosition">The yPostion for the instantiated prefabs</param>
public void InstantiateInCircle(GameObject prefab, Vector3 location, int howMany, float radius, float yPosition)
{
float angleSection = Mathf.PI * 2f / howMany;
for (int i = 0; i < howMany; i++)
{
float angle = i * angleSection;
Vector3 newPos = location + new Vector3(Mathf.Cos(angle), 0, Mathf.Sin(angle)) * radius;
newPos.y = yPosition;
Instantiate(prefab, newPos, prefab.transform.rotation);
}
}
public void InstantiateInCircle(GameObject prefab, Vector3 location, int howMany, float radius)
{
this.InstantiateInCircle(prefab, location, howMany, radius, location.y);
}
public void InstantiateInCircle(GameObject prefab, int howMany, float radius)
{
this.InstantiateInCircle(prefab, this.transform.position, howMany, radius);
}
// client EXAMPLE
private void Start()
{
this.InstantiateInCircle(this.prefabToInstantiate, new Vector3(0,0,0), 24, 2, 2);
}
}
Answer by Bhujanga · Dec 02, 2020 at 12:41 AM
Thanks for this awesome script @Raikish How could I add rotation to the prefabs? I want to instantiate the enemies in a 3d environment, but the game is supposed to be viewed 2d. So I want the circle to be "upright", zero on the z.position for all the instantiated prefabs. I tried to add a vector3 rotation to the function, but somehow cant make it work.