- Home /
Instantiate Prefabs on sphere surface(mini planet)
Hello Unity Community!: Im working on a mini planet project, but I have a problem. Using Unity free 4.3.4 on Mac.
Im trying to instantiate prefabs over a sphere surface, this prefabs consist of: Empty GameObject at (0,0,0) (it is also Center of the Planet).this Empty GO (pivot) is also a parent of the Prefab which is on sphere surface. So if I rotate parent, prefab is moving around the surface. I need to generate a fixed amount of prefabs BUT these SHOULD NOT COLLIDE with each other when generated. Also, if possible give any guidance on how to make those prefabs allways "readable"(to adjust their rotation so when planet is rotated it adjust is never upside down). This is my actual code:
public class SpawnTouchables : MonoBehaviour
{
public GameObject tokenPrefab;
public int maxTokenCreation=50;
public GameObject planet;
void Start()
{
transform.parent=planet.transform;
for(var tokenCount = 0; tokenCount < maxTokenCreation; tokenCount++ ){
float angleX = Random.Range(0,360);
float angleZ = Random.Range(0,360);
GameObject token=Instantiate (tokenPrefab,transform.position, Quaternion.Euler (angleX,0,angleZ) ) as GameObject;
chip.transform.parent=planet.transform ;
}
}
}
Here is the output:
https://www.dropbox.com/s/9ehk7pn6k79ruon/PrefabsOnPlanet.tiff
Thank you in advance,
Alonso G.
[1]: https://www.dropbox.com/s/9ehk7pn6k79ruon/PrefabsOnPlanet.tiff
You have a nice trick for spawning them around the surface of the sphere. I'd just like to offer another trick that would achieve the same result without needing the pivot empty parent.
You can rotate Euler angles by multiplying them by Quaternions. ( or multiply quaternions by euler, cant remember order; one will give an error ). Then you can create a Vector3 with your radius in one value and rotate that to get the position relative to the center of the sphere that you you want to spawn at. Then you can use Quaternion.Random.
Just another cool trick, nothing you have to switch to and it's very similar to yours. Only difference is that you don't have the empty parent giving a false location of 0, 0, 0. Good thinking!
I'm not sure what chip in your code is, but you can try this. Not elegant I know. you can create another layer for these prefabs and check them if they are colliding. as, you create the first one, create second, check if there is collision, if there is, change the rotation of second, if not third....
That has a very small chance of making the process of finding an open spot take a long time. And the more objects that are spawned, the higher that small chance gets.
The approach I took when solving a similar problem, is placing emtpy gameobjects in the sphere of locations that are allowed to spawn at. Then you can control the fact that it will never spawn on top of each other. Then store these empty gameobjects in a list, and pick a random number between 0 and the count of the list. This will give you a good location to spawn at.
Hello there, thank you for your comments. stevethorne, I like your approach, using Euler*Quaternions, although I dont know how it works haha. $$anonymous$$aybe you can show some code to give it a try?. It would be better not depending on Empty parent(called chip in script). Now, about prefabs not colliding: Using empty G.O, saving them on a list, and picking allowable locations from there will work. Although, I might not make them empty when choosing locations, otherwise they $$anonymous$$AY COLLIDE LATER, If prefabs "get bigger". So I might create locations first, using the biggest prefab. I believe that, if I want "random locations" I can pre-generate them using koray1396 approach, making some lists of them, then picking one of them AT RANDO$$anonymous$$ when scene begins, what do you think guys?. Other way may be, to make "rows and columns" on the sphere, like in a mapa mundi, like latitude longitude, so all look ordered.
Answer by alonsoGarrote · Mar 26, 2014 at 08:25 PM
Hello there, So, I decided to create a List of Vector3 positions so I could take one position at a time from that list on Object.Instantiate(). Here is the code:
public List<Vector3> CreateTokenPos()
{
for(var angleX=-150;angleX<0;angleX+=30)
{
for(var angleY=0;angleY<=330;angleY+=30)
{
tokenPosOnPlanet.Add(new Vector3(angleX,angleY,0));
}
}
return tokenPosOnPlanet;
}
I use, longitud latitude theory, so I take a position at each intersection.