Asteroid field

During our game Scavenger we wanted to create a infinite asteroid field where our ship could fly and find the pieces he needed.

To do so we needed to generate the field around the player, with a function we called:


GenerateAsteroidField(){

}

We will need a global GameObject variable in this exemple it’s called asteroidField The first thing we do in the GenerateAsteroidField() function is assign to the asteroidField Gameobject a new GameObject(), name it Asteroid field and change his position to the playerShipPosition

private GameObject asteroidField;
GenerateAsteroidField(){ 
asteroidField = new GameObject();
asteroidField.name = "Asteroid field";
asteroidField.transform.position = PlayerShip.transform.position;
} 

By doing so we can act on all asteroid that we will set as child of this newly created GameObject. Now for the creation of asteroids it’s a simple double for, inside we instantiate an asteroid and position with two random position around the asteroidField GameObject.

 
private GameObject asteroidField;
 GenerateAsteroidField(){
 asteroidField = new GameObject();
 asteroidField.name = "Asteroid field";
 asteroidField.transform.position = PlayerShip.transform.position;
for (int i = 0; i < AsteroidGenereted; i++)
        {
            for (int j = 0; j < AsteroidGenereted; j++)
            {
                GameObject SpaceJunk = Instantiate(OneAsteroidGameObject);
                SpaceJunk.transform.position = new Vector2(Random.Range(-20, 20) + PlayerShip.transform.position.x, Random.Range(-20, 20) + PlayerShip.transform.position.y);
            }
        }
 } 

But before we put it as a child of the AsteroidField GameObject we should check his distance to the player,and if too close move the asteroid somewhere else. We add a public function to the asteroid that we will access from our current script. The asteroid will have a recursive function we called it Relocalisation() and it redo the change of position with the random added to the x and y. Then the function check the distance between the asteroid and the player and if it’s too close call herself (set to be away enough to be out of the camera), repeating the process until the asteroid is far enough from the player (since it’s a recursive function think about the exit conditions if they can’t be completed the script will just loop to oblivion).

Now that we have made the asteroids we must also set them as child of the AsteroidField Gameobject and make them rotate

The asteroidField’s Code

 
private GameObject asteroidField;
 GenerateAsteroidField(){
  asteroidField = new GameObject();
  asteroidField.name = "Asteroid field";
  asteroidField.transform.position = PlayerShip.transform.position;
  for (int i = 0; i < AsteroidGenereted; i++) {
   for (int j = 0; j < AsteroidGenereted; j++) {
   GameObject asteroid = Instantiate(OneAsteroidGameObject);
   SpaceJunk.transform.position = new Vector2(Random.Range(-20, 20) + PlayerShip.transform.position.x, Random.Range(-20, 20) + PlayerShip.transform.position.y);
    if (Vector2.Distance(asteroid.transform.position,PlayerShip.transform.position)<5){
         SpaceJunk.GetComponent<Debris>().Relocalisation();
    }
    asteroid.transform.SetParent(asteroidField.transform);
    asteroid.transform.Rotate(Vector3.forward * Random.Range(0, 360));
   }
  }
 }
 

The asteroid’s code

public void Relocalisation()
    {
        transform.position = new Vector2(Random.Range(-20, 20) + transform.position.x, Random.Range(-20, 20) + transform.position.y);
        if (Vector2.Distance(transform.position, PlayerShip.transform.position) < 15)
        {
            Relocalisation();
        }
    }

Now  all we need is to check the distance between the ship and the closest asteroid, once the distance is big enough that means we are out of the asteroid field and ready to recreate the asteroid field . we do this by getting all the asteroid in a variable (in our game we used the GameObject.Find() function but there’s is many way to accomplish this) and calculate the distance between the ship and all asteroids and saving the closest distance, once this distance is greater than a threshold we assign we launch the GenerateAsteroidField() function


//Check the distance between the asteroid field and the player and if far enough create the new asteroid field

private void DistanceCheck()
{

//Set an impossible high distance
float distance = 1000000;

// for each asteroid
foreach (var item in GameObject.FindGameObjectsWithTag("asteroid")){

//If the distance between the asteroid and player is smaller than the variable distance, the variable distance become this new distance
if (Vector2.Distance(item.transform.position,PlayerShip.transform.position)<distance){
distance = Vector2.Distance(item.transform.position, PlayerShip.transform.position);
}
}

//If the shortest distance is smaller than our threshold the asteroid field is destroyed and another one is created
if (distance>10){
Destroy(asteroidField);
GenerateAsteroidShield();
}
}