1
\$\begingroup\$

I have an problem where I instantiate a GameObject and it keeps on instantiating a million times over, even though I put the line of code under the start function.

I am trying to have the player collide with the coin(then a point is added to your score) , then the coin deletes itself and then re-instantiates at a random coordinate, but I cant get past the initial instantiation.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Coin : MonoBehaviour {
public GameObject coins;
Vector2 randomPosition; 
public UIScript _UIScript;

// Use this for initialization
void Start () {
    _UIScript = GameObject.FindWithTag("UI").GetComponent<UIScript>();
    randomPosition = new Vector2(Random.Range(-8f, 8), Random.Range(-4f, 4f));
    Instantiate(coins, randomPosition, Quaternion.identity);
}


// Update is called once per frame
void Update () {

}
private void OnTriggerEnter2D(Collider2D coinCollision)
{
    switch(coinCollision.tag)
    {
            case "Player":
            collisionWithPlayer();
            break;
    }
}
private void collisionWithPlayer()
{
    _UIScript.highScore = _UIScript.highScore + 1; 
    Object.Destroy(coins);
}
}
\$\endgroup\$
  • \$\begingroup\$ Well I'm not an expert with Unity, but if your public GameObject coins contains game objects of type public class Coin, and that Start is called when instantiated, you have an infinite loop of creation of objects. Maybe you could put the call to instantiate in collisionWithPlayer instead, just before calling Object.Destroy(coins);. \$\endgroup\$ – Vaillancourt Apr 13 '17 at 1:41
  • \$\begingroup\$ Ok, sweet. That worked perfectly. However, how do I instantiate the coin at a random position each game? \$\endgroup\$ – BigBob Apr 13 '17 at 2:51
  • \$\begingroup\$ And why does it cause an infinite loop? \$\endgroup\$ – BigBob Apr 13 '17 at 2:58
  • \$\begingroup\$ @BigBob Because you're telling the coin to make another coin and that coin that was just made makes another one, and that one another one, and so on and so forth. Also, your first comment is another question in and of itself. \$\endgroup\$ – John Hamilton Apr 13 '17 at 5:25
6
\$\begingroup\$

Expanding my comment.

Well I'm not an expert with Unity, but here is what I notice.

If your variable public GameObject coins contains game objects of type Coin, and that Start is called when the object is instantiated, you have an infinite loop of creation of objects because Start will call instantiate, which will have Start called on the newly created object, which call instantiate, which will have Start called on the newly created object, which call instantiate, which will have Start called on the newly created object, which call instantiate, which will have Start called on the newly created object, which call instantiate, which will have Start called on the newly created object, which call instantiate, which will have Start called on the newly created object, which call instantiate, which will have[...].

Maybe you could put the call to instantiate in collisionWithPlayer instead, just before calling Object.Destroy(coins);, like such:

public class Coin : MonoBehaviour {
    public GameObject coins;
    public UIScript _UIScript;

    // Use this for initialization
    void Start () {
        _UIScript = GameObject.FindWithTag("UI").GetComponent<UIScript>();
        Vector2 randomPosition = new Vector2(Random.Range(-8f, 8), Random.Range(-4f, 4f));
        // Instead of setting the position of the next object here, set the position of this 
        // object on its Start
        transform.SetPositionAndRotation(randomPosition, Quaternion.identity);
    }

    // Update is called once per frame
    void Update () {
    }

    private void OnTriggerEnter2D(Collider2D coinCollision)
    {
        switch(coinCollision.tag)
        {
            case "Player":
                collisionWithPlayer();
                break;
        }
    }

    private void collisionWithPlayer()
    {
        _UIScript.highScore = _UIScript.highScore + 1; 
        // Create the new object here, and let it position itself in its start method. 
        Instantiate(coins); 
        Object.Destroy(coins);
    }
}

Now I wouldn't say this is the way to do it (as I said, I'm not an expert with Unity), but this could probably do what you need.

\$\endgroup\$
  • \$\begingroup\$ This is one of the better ways to instantiate. An object should never instantiate itself as you have said. This should be picked as the answer imho, because it addresses the problem and even offers an alternative where it doesn't have to. \$\endgroup\$ – John Hamilton Apr 14 '17 at 5:37

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.