当游戏对象在与某些东西发生碰撞时被销毁时,逻辑问题会产生一定数量的游戏对象吗?

时间:2016-05-20 05:21:11

标签: c# unity3d

我在使用C#进行Unity基本游戏时遇到了两难 - 我需要在随机位置生成10个立方体,但是一旦生成立方体,如果它检测到与此处的另一个游戏对象发生碰撞,则将其销毁脚本附加到多维数据集对象:

void OnCollisionStay(Collision col){

        if (col.gameObject.tag == "Maze" || col.gameObject.tag == "Player") {

            //Destroy cube
            Destroy(this.gameObject);
            spawnCubes.numCubesExist--;

            Debug.Log ("touching!!" + spawnCubes.numCubesExist);

            spawnCubes.touchedMaze = true;

        }
    }

在我场景中的另一个脚本中,我在这里生成了多维数据集。我使用public static int numCubesExist来枚举场景中的多维数据集的数量(虽然这不起作用)和NUMTOBESPAWNED来设置应该在场景中结束的多维数据集的数量。

在多维数据集脚本中,如果检测到冲突,并且numCubesExist生成多维数据集,则cubeSpawner ();减1。我的逻辑是我的while语句将继续产生UNTIL numCubesExist == NUMTOBESPAWNED,但这不会发生。

void Start () {

        while(numCubesExist <= NUMTOBESPAWNED)
        {
            cubeSpawner ();
        }

    }
void cubeSpawner()
    {
        //Random textures
        switch (Random.Range (0, 3)) {
        case 0:
            cube.GetComponent<Renderer> ().material = color1;

            break;

        case 1:
            cube.GetComponent<Renderer> ().material = color2;

            break;

        case 2:
            cube.GetComponent<Renderer> ().material = color3;
            break;

        case 3:
            cube.GetComponent<Renderer> ().material = color4;

            break;

        }

        //Random positions
        if (UIManagerScript.sceneNum == 0) {
            position = new Vector3 (Random.Range (7.0F, 26.0F), (float)1.4, Random.Range (-9.0F, 10.0F));
            Debug.Log (position);
        }
        else if(UIManagerScript.sceneNum == 1) {
            position = new Vector3 (Random.Range (7.0F, 47.0F), (float)1.4, Random.Range (-9.0F, 10.0F));
            Debug.Log (position);
        }
        else if(UIManagerScript.sceneNum == 2) {
            position = new Vector3 (Random.Range (-4.7F, 44.0F), (float)1.4, Random.Range (-23.0F, 25.0F));
            Debug.Log (position);
        }

        //spawn
        Instantiate (cube, position, Quaternion.identity);
        Debug.Log ("spawned it!"+numCubesExist);
        numCubesExist++;
    }

立方体脚本碰撞中的My Debug.Log语句在打印完所有spawn语句后打印,所以我看到的是多维数据集产生正确的数字,然后其中一半被销毁并且未被替换由OnCollisionStay。所以我总是留下比NUMTOBESPAWNED更少的立方体。

我是Unity的新手 - 实现这一目标的最佳方法是什么?我应该在哪里调用我的while循环(在更新中只产生一百万个立方体)?

编辑以枚举多维数据集:

GameObject[] allObjects = GameObject.FindGameObjectsWithTag("blueCube");
        foreach (GameObject go in allObjects) {
            cubesInScene++;
        }

1 个答案:

答案 0 :(得分:0)

这就是我所看到的,我希望这有帮助!

  1. 你的产生者并不保证立方体不会在下一个(或进入)“迷宫”或“玩家”对象中产生,所以很可能它偶尔发生并且你的立方体在它们产生后立即被销毁。正如“Nick Otten”所强调的那样,当这种情况发生时你的生成循环已经结束,因此不会产生新的立方体来代替被破坏的那些。
    为了解决这个问题,你可以做几件事。以下是一些例子:

    • 在场景中创建spawner并保证“Maze”和“Player”都在预定范围之外(比如10个单位的球体),以及保证在里面产生立方体;你可以简单 - 编码 - 并为你的产生者的“地球”添加一个对撞机,并IgnoreLayerCollision使不需要的物品击退(“留在外面”)和其他人通过(“呆在里面”) )。例如。立方体击退,玩家留在里面,反之亦然。
    • 您可以在“产卵阶段”中应用不同的碰撞机制。即在OnCollisionEnter上,你使对象相互击退/反弹/等,而不是立方体被摧毁。一旦产卵阶段结束,保证没有任何东西触及你可以切换到“破坏机制”/“播放模式”
    • 缓慢而且开销很大,所以我不推荐它,但是你可以继续产卵和产卵,直到所有的立方体都停留(即没有产生它们被破坏)。
  2. 而不是“numCubesExist”等,为什么不创建一个立方体预制队列(并在脚本中隐藏/重新排列它们而不是销毁)?这是一个很好的教程,如何执行此操作:Object Pooling Tutorial我还推荐Sebastian的其他教程,他在教授Unity 方面做得很好)

  3. 在你的立方体spawner方法中,为什么不做这样的事情而不是开关呢?

    //class variable
    private Material[] colorMats; //fill up in Start() with color mats.
    //then in cubeSpawner:
    cube.GetComponent<Renderer>().material = colorMats[Random.Range(0, colorMats.Length)];
    所以每当你改变你的材料时(例如添加一个新材料) ),你必须在一个地方,在Start()

  4. 中改变你的初始化代码