I randomly instantiate game objects, to create a dynamic "sky map". But some planets appear on top of another ones. I'm trying to solve this problem with Collision detection and Colliders, but it doesn't seem to work. How to solve this problem? Maybe there is a better and easier way to do this?

Here is the code I use:


for (int i = 0; i<planet_one_count; i++) {
            var planets = Instantiate (planet, new Vector3 (Random.Range (-9.0F, 9.0F)+(Random.value), Random.Range (-4.0F, 3.0F)+(i*Random.value), 0), new Quaternion (0, 0, 0, 0)) as GameObject;
            planets.transform.localScale = planets.transform.localScale*Random.Range(0.75f,1);
        for (int i = 0; i<cometcount; i++) {
            var comets = Instantiate (comet, new Vector3 (Random.Range (-9.0F, 9.0F)+(Random.value), Random.Range (-4.0F, 3.0F)+(i*Random.value), 0),Quaternion.Euler(0,0,Random.Range(-34,-24))) as GameObject;
            comets.transform.localScale = comets.transform.localScale*Random.Range(0.75f,1);
        for (int i = 0; i<planet_two_count; i++) {
            var planets_two = Instantiate (planet_two, new Vector3 (Random.Range (-9.0F, 9.0F)+(Random.value), Random.Range (-4.0F, 3.0F)+(i*Random.value), 0), new Quaternion (0, 0, 0, 0)) as GameObject;
            planets_two.transform.localScale = planets_two.transform.localScale*Random.Range(0.75f,1);


void OnCollisionStay2D(Collision2D coll){
    coll.gameObject.transform.position = new Vector3(coll.gameObject.transform.position.x+0.1f,coll.transform.position.y+0.1f,0);
  • \$\begingroup\$ possible duplicate of Random enemy placement on a 2d grid \$\endgroup\$ Feb 20 '15 at 15:08
  • \$\begingroup\$ What exactly is the ideal scenario? ("Dynamic sky map" doesn't mean much to me.) \$\endgroup\$
    – Anko
    Feb 22 '15 at 11:03
  • \$\begingroup\$ Ideal scenario is when none of the objects are on top of each other (there has to be max 28 objects) \$\endgroup\$
    – yamahamm
    Feb 22 '15 at 11:04
  • \$\begingroup\$ this doesn't answer your question, but would help clean up your code very slightly: instead of wiring new Quaternian (0, 0, 0) you can just write Quaternion. identity. Also the "Creating a Roguelike" unity tutorials have some good example of random placement. \$\endgroup\$ Apr 23 '15 at 22:44

Depending on the game's field of play's size, divide the area you wish to populate with planets into a grid where each square can contain a planet in it's entirety. Now Randomly decide if there is a planet in each square of the grid, by randomizing a number.

NUMBER_OF_SQUARES = width * height;

planetsLeft = NUMBER_OF_PLANETS;
while (planetsLeft > 0)
for (int i = 0; i < NUMBER_OF_SQUARES; i++)
    if (Random.Range(0.0, 1.0) > NUMBER_OF_PLANETS / NUMBER_OF_SQUARES)
        if (gird[i] == false)
            grid[i] = true;
            // planet[i].xy = grid[i].xy + small_randomness_inside_square;

Okay, I'm not going through debugging your code because I think there is an easier way. Rather than checking for per pixel or rectangle collision, why not maintain a list of Vector3s and a list of floats? Populate the list of Vector3s with positions and the list of floats with the radius of the planets.

private bool AddPlanetIfNoCollision(Vector3 position, float radius)
    if (positions.Length > 0)
        for (int i = 0; i < positions.Length + 1; i++)
            if (Vector3.Distance(positions.elementAt(i), position) > radius + radii.elementAt(i))
                return false;
    return true;

Obviously that code is not something you'd copy paste into your program, it's just a concept. But it will work fine as long as your planets are circular.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.