如何阻止 Unity 游戏创建无限游戏对象

How to stop a Unity game from creating infinity game objects

提问人:Lukinator 提问时间:8/13/2023 更新时间:8/16/2023 访问量:39

问:

我创建了一个简单的Unity游戏,它是关于掉落的立方体的。你必须控制它们,并将相同颜色的立方体放在一起。在 2 或 3 个通常掉落的立方体之后,游戏会创建数百个立方体,Unity 崩溃。无限立方体每种颜色有 4 个不同的立方体预制件。我为它们中的每一个添加了 createCube 脚本。有 Create() 函数,它在碰撞后被调用:

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();
    }
}

还有 GameObject 地面,用于捕获立方体。它还通过掉落第一个立方体来开始游戏:

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;
        }
    }
}

我试图在碰撞后启用脚本,以便立方体无法创建新的脚本,我试图给它们不同的标签,但没有任何改变。我以为这是因为一个立方体与多个物体发生碰撞(例如,地面和立方体同时发生碰撞),但当立方体仅与其他立方体发生碰撞时,也会发生这种情况。

C# unity-游戏引擎- 游戏开发

评论

1赞 Retired Ninja 8/13/2023
去猜测碰撞实例化一个对象,该对象立即碰撞并实例化一个对象,永远重复越来越多的碰撞,因为它们都是重叠的。

答:

0赞 QueryKiller 8/13/2023 #1

立方体无休止地生成,因为它们在创建时会立即发生碰撞,从而导致生成循环。在碰撞后生成新立方体之前添加延迟。我继续在 OnCollisionEnter2D 中实现了冷却时间,以避免快速的背靠背生成。

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;
    private float cooldown = 0.5f;
    private float nextSpawnTime = 0;

    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)
    {
        if (Time.time > nextSpawnTime)
        {
            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();
            nextSpawnTime = Time.time + cooldown;
        }
    }
}

评论

0赞 Lukinator 8/16/2023
谢谢你的回答,但不幸的是问题仍然是一样的
0赞 Lukinator 8/16/2023 #2

由于我不想再处理这个问题了,所以我寻找替代方案,发现:

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

在另一个脚本中:

public createCube other;

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

现在,立方体不是在碰撞后生成,而是在 2 秒后生成。这并不完全是我想要的,但它有效。