Search code examples
c#unity-game-enginegame-development

How to stop a Unity game from creating infinity game objects


I created a simple Unity game, which is about falling cubes. You have to control them and bring cubes with the same color together. After 2 or 3 normally falling cubes, the game creates hundreds of cubes and Unity crashes. Infinity cubes There are 4 different cube prefabs for each color. To each of them I added the createCube script. There is the Create() function, which is called up after a collision:

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

public class createCube : MonoBehaviour
{
    public GameObject redPrefab;
    public GameObject greenPrefab;
    public GameObject bluePrefab;
    public GameObject yellowPrefab;
    private createCube script;
    private SpriteRenderer spriteR;

    void Create()
    {
        int zufall = Random.Range(1,5);
        switch(zufall)
        {
            case 1: Instantiate(redPrefab, new Vector3(0,4.2f,0), Quaternion.identity); break;
            case 2: Instantiate(greenPrefab, new Vector3(0,4.2f,0), Quaternion.identity); break;
            case 3: Instantiate(bluePrefab, new Vector3(0,4.2f,0), Quaternion.identity); break;
            default: Instantiate(yellowPrefab, new Vector3(0,4.2f,0), Quaternion.identity); break;
        }
    }
    void OnCollisionEnter2D(Collision2D coll)
    {
        GameObject otherObject = coll.gameObject;
        script = GetComponent<createCube>();
        script.enabled = false;      
        if (otherObject.CompareTag("Ground"))
        {
            if (GetComponent<SpriteRenderer>().sprite.name == "red")
            {
                gameObject.tag = "Deadred";
            }
            else if (GetComponent<SpriteRenderer>().sprite.name == "green")
            {
                gameObject.tag = "Deadgreen";
            }
            else if (GetComponent<SpriteRenderer>().sprite.name == "blue")
            {
                gameObject.tag = "Deadblue";
            }
            else
            {
                gameObject.tag = "Deadyellow";
            }

        }
        else if (otherObject.CompareTag("Deadred") || otherObject.CompareTag("Deadgreen") || otherObject.CompareTag("Deadyellow") || otherObject.CompareTag("Deadblue"))
        {
            if (GetComponent<SpriteRenderer>().sprite.name == "red")
            {
                gameObject.tag = "Deadred";
            }
            else if (GetComponent<SpriteRenderer>().sprite.name == "green")
            {
                gameObject.tag = "Deadgreen";
            }
            else if (GetComponent<SpriteRenderer>().sprite.name == "blue")
            {
                gameObject.tag = "Deadblue";
            }
            else
            {
                gameObject.tag = "Deadyellow";
            }
        }

        else if (otherObject.CompareTag("Deadred") && gameObject.GetComponent<SpriteRenderer>().sprite.name == "red")
        {
            Destroy(otherObject);
            Destroy(gameObject);
        }
        else if (otherObject.CompareTag("Deadgreen") && gameObject.GetComponent<SpriteRenderer>().sprite.name == "green")
        {
            Destroy(otherObject);
            Destroy(gameObject);
        }
        else if (otherObject.CompareTag("Deadblue") && gameObject.GetComponent<SpriteRenderer>().sprite.name == "blue")
        {
            Destroy(otherObject);
            Destroy(gameObject);
        }
        else if (otherObject.CompareTag("Deadyellow") && gameObject.GetComponent<SpriteRenderer>().sprite.name == "yellow")
        {
            Destroy(otherObject);
            Destroy(gameObject);
        }
        Create();
    }
}

There is also the GameObject ground, which catches the cubes. It also starts the game by dropping the first cube:

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

public class starter : MonoBehaviour
{
    public GameObject redPrefab;
    public GameObject greenPrefab;
    public GameObject bluePrefab;
    public GameObject yellowPrefab;

    void Start()
    {
        int zufall = Random.Range(1,5);
        switch(zufall)
        {
            case 1: Instantiate(redPrefab, new Vector3(0,4.2f,0), Quaternion.identity); break;
            case 2: Instantiate(greenPrefab, new Vector3(0,4.2f,0), Quaternion.identity); break;
            case 3: Instantiate(bluePrefab, new Vector3(0,4.2f,0), Quaternion.identity); break;
            default: Instantiate(yellowPrefab, new Vector3(0,4.2f,0), Quaternion.identity); break;
        }
    }
}

I tried to enable the script after colliding so the cube can't create a new one and I tried to give them different tags, but nothing changed. I thought it's because a cube collides with multiple objects (for example with the ground and a cube the same time), but it also happens when the cube collides only with an other cube.


Solution

  • Since I didn't want to deal with the problem any longer, I looked for an alternative and found that:

    public void Repeating()
    {
        InvokeRepeating ("Create",3.0f,2.0f);
    }
    

    and in an other script:

    public createCube other;
    
    void Start()
    {
        other.Repeating();
    }
    

    Now the cube spawns not after a collision, but after 2 seconds. It's not exactly what I wanted, but it works.