使孩子超越界限

时间:2019-06-10 14:12:53

标签: c# unity3d

我不知道我的代码有什么问题。生成的第一种情况可以正常工作,但是此后会收到错误消息“ Transform child out of bounds”。那是因为只考虑了第一个元素。这些物体是由一个名为“ Spawner”的物体生成的,并附加了脚本“ Mandibula”。

我试图放入一个循环,但是没有用。我该如何解决?

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

public class Alavanca : MonoBehaviour
{
    //Pegar o player pra impedir ele de largar algum item na bancada
    private PlayerController Player;
    //Pegar a mandibula pra poder acionar a contagem dos espaços
    private Mandibula Mandibula;
    //pegar o spawner, pra poder pegar a bancada pelo seu filho
    private GameObject Spawner;

    void Start()
    {
        Player = GameObject.FindWithTag("Player").GetComponent<PlayerController>();
        Spawner = GameObject.FindWithTag("Spawner");
    }

    private void OnTriggerStay(Collider other)
    {
        if (other.tag == "PlayerCollider")
        {
            Player.PodeLargar = false;
        }

        if (Input.GetButtonDown("Jump") && other.tag == "PlayerCollider")
        {
            try
            {
                for (int i = 0; i < Spawner.transform.childCount; i++)
                {
                    Mandibula = Spawner.transform.GetChild(i).GetComponent<Mandibula>();
                     Mandibula.Contar_Espaços();

                }
            }
            catch
            {

                print("Ainda não tem caso");
            }
        }
    }

    private void OnTriggerExit(Collider other)
    {
        if (other.tag == "PlayerCollider")
        {
            Player.PodeLargar = true;
        }
    }
}

[从答案中添加]

方法Contar_Espaços在脚本Mandibula中:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Mandibula : MonoBehaviour
{
    //define o número de espaços
    public ValidadorEspaço1[] espaços;

    //variável para acessar o script do gamecontroller
    private GameController gameController;
    private GameObject controller;

    // Start is called before the first frame update
    void Start()
    {
        controller = GameObject.FindGameObjectWithTag("Controller");
        //acessa o script GameContoller
        gameController = controller.GetComponent<GameController>();
    }

    // Update is called once per frame
    public void Contar_Espaços()
    {
        gameController.contadorPontos = 0;
        for (int i = 0; i <= 13; i++)
        {
            if (espaços[i].DenteCerto)
            {
                gameController.contadorPontos++;//se os dentes e grampos são colocados no lugar certo, o contador incrementa
            }
        }

        if (gameController.contadorPontos == 14)
        {
            //se o jogador colocar todos os dentes e grampos nos lugares corretos, ele soma 1 ponto
            gameController.CasosResolvidos++;
            //após somar um ponto, a mandíbula é destruída para que outra seja spawnada no lugar dela
            Destroy(this.gameObject);
        }
    }
}

2 个答案:

答案 0 :(得分:1)

在以前的帖子中,我们可以看到您有一个

if (gameController.contadorPontos == 14)
{
    //se o jogador colocar todos os dentes e grampos nos lugares corretos, ele soma 1 ponto
    gameController.CasosResolvidos++;

    //após somar um ponto, a mandíbula é destruída para que outra seja spawnada no lugar dela
    Destroy(this.gameObject);
}

在您的Contar_Espaços()中。

如果考虑一下:销毁子对象的那一刻显然childCount会变得无效,因此迭代变量i也将无效,因为它现在可以到达一个索引,该索引中没有子对象可以找到了。


我建议您选择给您的方法一个bool作为返回类型,例如

public bool Contar_Espaços()
{
    gameController.contadorPontos = 0;
    for (int i = 0; i <= 13; i++)
    {
        if (espaços[i].DenteCerto)
        {
            //se os dentes e grampos são colocados no lugar certo, o contador incrementa
            gameController.contadorPontos++;
        }
    }

    if (gameController.contadorPontos == 14)
    {
        //se o jogador colocar todos os dentes e grampos nos lugares corretos, ele soma 1 ponto
        gameController.CasosResolvidos++;

        //após somar um ponto, a mandíbula é destruída para que outra seja spawnada no lugar dela
        return true;
    }

    return false;
}

,现在宁愿收集所有返回true的元素,并在以后销毁它们,例如使用Linq Where

using System.Lynq;

...

if (Input.GetButtonDown("Jump") && other.tag == "PlayerCollider")
{
    var todestroy = Spawner.GetComponentsInChildren<Mandibula>(true).Where(m => m.Contar_Espaços());
    foreach(var mand in todestroy) 
    {
        Destroy(mand.gameObject);
    }   
}

这是写作的捷径

if (Input.GetButtonDown("Jump") && other.tag == "PlayerCollider")
{
    var todestroy = new List<Mandibula>();

    // gets all Mandibula references from this and any child object
    // (add parameter true for also getting currently disabled or inactive ones)
    var mandibulas = Spawner.GetComponentsInChildren<Mandibula>(true);

    foreach(var m in mandibulas)
    {
        if(m.Contar_Espaços()) todestroy.Add(m);
    }

    foreach(var mand in todestroy) 
    {
        Destroy(mand.gameObject);
    }   
}

通常请记住,该社区(与所有其他StackExchange社区一样)为英语,因此请删除注释或将其翻译为英语,以便我们也使用它们。您应该总是习惯用英语编码和评论。这是 全局编码语言;)

答案 1 :(得分:0)

您可以尝试使用GetComponentsInChildren

...

if (Input.GetButtonDown("Jump") && other.tag == "PlayerCollider")
{
    var mandibulas = Spawner.GetComponentsInChildren<Mandibula>();
    foreach(Mandibula mand in mandibulas) 
    {
        mand.Contar_Espaços();
    }   
}

...