How can I Instantiate two new GameObjects at the same time? (Attempting Asteroids style game)

Hi all,

I haven’t been at my computer learning code or game dev in a few months and am just starting again. I am trying to make a game very similar to Asteroids. In 3d but fixed camera from above so basically disregarding the Y Axis at the moment.

I have everything working fine so far such as the rocket stays in middle and can rotate, and fire weapon. The Asteroids for now all come from the top side of the screen, and have some code to randomise the X location and speeds.

When the laser hits the Asteroid I want it to destroy that Asteroid and create two more that are half the size and with a Rotation added of 45/-45 degrees.

I have the code that I thought would work but it is only creating one more and not two. (note: as you’ll see I have tried making tempAsteroid2 and even asteroidPrefab2, before this I just had the one which I tried to instantiate twice).

What am I missing? why does this code not make two more appear upon laser collision??

Any help massively appreciated as always. Many thanks:

public class Asteroid : MonoBehaviour {
float speed;
public GameObject asteroidPrefab, asteroidPrefab2;
public int sizeKey = 2;
// Use this for initialization
void Start () {
    if (sizeKey < 1)
    {
        Destroy(this.gameObject);
    }
    transform.position.Set(transform.position.x, 0f, transform.position.y);
    speed = Random.Range(0.5f, 2f);
}

// Update is called once per frame
void Update () {
    GetComponent<Rigidbody>().transform.Translate(Vector3.forward * speed * Time.deltaTime);
}

private void OnTriggerEnter(Collider other)
{
    if (other.tag == "Laser")
    {
        BreakAsteroidInHalf();
        Destroy(other.gameObject);
    }
}

void BreakAsteroidInHalf()
{
    GameObject tempAsteroid = asteroidPrefab;
    tempAsteroid.transform.position = transform.position;
    tempAsteroid.transform.Rotate(0, -45, 0);
    tempAsteroid.transform.localScale *= 0.5f;
    tempAsteroid.GetComponent<Asteroid>().sizeKey -= 1;
    Instantiate(tempAsteroid);
    GameObject tempAsteroid2 = asteroidPrefab2;
    tempAsteroid2.transform.position = transform.position;
    tempAsteroid2.transform.Rotate(0, 45, 0);
    tempAsteroid2.transform.localScale *= 0.5f;
    tempAsteroid2.GetComponent<Asteroid>().sizeKey -= 1;
    Instantiate(tempAsteroid2);
    Destroy(this.gameObject);
    Debug.Log("Asteroid destroyed and replaced by 2 more");

}

I see 2 issues with your code.

First of all, you are modifying the prefab. You shouldn’t be doing that when instantiating objects, since you are basically changing the template from which subsequent objects will be created and that may have unexpected results.

What you need to do to solve this is very simple just combine the Instantiate(tempAsteroid); with the GameObject tempAsteroid line.

//Instead of having this:
GameObject tempAsteroid = asteroidPrefab;
//bla bla
Instantiate(tempAsteroid);
//You should have this:
GameObject tempAsteroid = Instantiate(asteroidPrefab);
//bla bla
//And so you would do the same for tempAsteroid2
//As a side note, you shouldn't be needing two prefabs for this. One should be enough since you're only changing a rotation, but, if it is simpler for you then leave it like that

The second issue (and the one that I think is mainly causing your problem) is that you are placing both the newly instantiated objects in the exact same position and with the exact same scale, this might be making it so you can’t see one of them since the other one is on top of it. Have you checked the hierarchy of objects to see if there’s really just one object? Try placing them in different positions, with different scales maybe just to be sure.

Hope this helps!

EDIT: Oh, I am dead wrong, see MacDx’s comment.


Hmmmm…

GameObject tempAsteriod = Instantiate(/*insert thingos here*/);

Maybe?
An asteroid prefab probably isn’t a game object.

Ohhhhhh! I see!

public GameObject asteroidPrefab, asteroidPrefab2;

Yah wrote this, but never assigned it to any value! Hah, I see how that would make things even more confusing! Basically you made empty game objects in your code asteriodPrefab, asteriodPrefab2, then later on created tempAsteriod1 and tempAsteriod2, assigning their reference to the empty game objects. Thus… of course nothing is created!
The asteroid prefab you want to use isn’t a game object, it’s this… data-thing, which you feed into the instantiate method to create a game object with the properties of the prefab. ( I think).
Does that make sense?