如何在创建新的之前销毁所有子对象?

时间:2016-09-30 13:36:19

标签: c# unity3d

在这个函数中,我对子节点进行循环并销毁它们。 问题是,例如,如果我有1个孩子,并且在脚本中的检查器中,我将子项的值从1更改为10,那么它将向已存在的子项添加10个新子项。所以我现在有11.然后如果我将值从10更改为100,我将有111,如果我改回1,那么我将有112。

我想让它在游戏运行时做什么如果我改变值首先销毁所有的孩子然后根据最后更改的值创建新的一次。因此,如果我在运行游戏时的值为10并且我将其更改为100则首先删除10然后添加新的100.如果我从10更改为1则首先删除10然后添加1.

我一般想要做的是在游戏运行时更改_birdscount的值会改变孩子的数量。

在剧本的顶部:

public CameraControl cameraControl;
public Object birdPrefab;
public Transform birdParent;
private Transform cameraObj;
public Transform[] instancePoints;
public int _birdscount;

在Start功能中,我添加了一个StartCoroutine:

void Start()
  {
    if( globalSettings == null )
    {
      settings = LoadSettings();
      globalSettings = settings;
    }
    else
      settings = globalSettings;

    InstantiateBirds();
    cameraControl.Enabled = !settings.showSettingsWindow;

    StartCoroutine(_WatchBirdCount());
  }

然后在一个函数中,它会检查值_birdscount是否发生了变化,然后销毁这些子并创建一次:

int prevBirdCount;
    List<Transform> transforms = new List<Transform>();
    IEnumerator _WatchBirdCount()
    {
        prevBirdCount = _birdscount;

        while(true)
        {
            if(_birdscount != prevBirdCount)
            {
                prevBirdCount = _birdscount;
                //Do something
                foreach (Transform child in birdParent)
                {
                    //child is your child transform
                    Destroy(child);
                }
                InstantiateBirds();
            }
            yield return 0; //Wait a frame before checking again
            {
            }
        }
    }

制作子项的InstantiateBirds()函数: 我在这个函数中添加了一行:

sts.BirdsCount = prevBirdCount;

下面:

void InstantiateBirds()
  {
    var ip = instancePoints[settings.instancePointNum];
    var sts = settings.boidSettings[settings.instancePointNum];

    sts.Trace = ip.GetComponent<Trace>();

    const float size = 0.1f;

    cameraObj = InstantiateBird( ip.position, ip.rotation, sts ).transform;
    cameraControl.Target = cameraObj;
         sts.BirdsCount = prevBirdCount;
    MathTools.FillSquareUniform( sts.BirdsCount, delegate ( int x, int y )
    {
      if( x != 0 || y != 0 )
        InstantiateBird(
          cameraObj.position + new Vector3( size * x, size * y, Random.Range(-size, size) ),
          MathTools.RandomYawPitchRotation(),
          sts
        );
    });
  }

如果需要InstantiateBird函数:

private GameObject InstantiateBird( Vector3 position, Quaternion rotation, Boid.Settings boidSettings )
  {
    var obj = (GameObject)Instantiate( birdPrefab, position, rotation );
    var boid = obj.GetComponent<Boid>();

    obj.transform.parent = birdParent;
    boid.SettingsRef = boidSettings;
    boid.DebugSettingsRef = settings.debugSettings;

    return obj;
  }

1 个答案:

答案 0 :(得分:1)

这些方面的东西应该这样做:

public void ClearChilds(Transform parent)
{
    foreach(Transform child in parent)
    {
        Destroy(child.gameObject);
    }
}

您的代码中确实包含以下几行:您只需在变换(Destroy)上调用child,而不是游戏对象(child.gameObject)。

修改
我写了一些代码,它将根据公共字段的数量(childCount)更新脚本所在对象的子项数。 currentChildCount仅用于测试公众(这是您的prevBirdCount)。 该脚本将首先销毁所有旧孩子,然后实例化新孩子。

为了测试这段代码,您只需要将一些对象作为父级放置此脚本,并将一些预制件用作子级。 (我没有摆弄定位。)

using UnityEngine;
using System.Collections;

public class ChildrenHandler : MonoBehaviour {

    public GameObject childPrefab;

    public int childCount;

    public int currentChildCount;

    // Use this for initialization
    void Start ()
    {
        InstantiateChildren(childCount);

        StartCoroutine(CheckChildCount());
    }

    IEnumerator CheckChildCount()
    {
        currentChildCount = childCount;

        while(true)
        {
            if(childCount != currentChildCount)
            {
                foreach(Transform child in transform)
                {
                    Destroy(child.gameObject);
                }

                InstantiateChildren(childCount);
            }
            yield return null;
        }   
    }

    private void InstantiateChildren(int num)
    {
        for(int i = 0; i < num; i++)
        {
            GameObject go = (GameObject)Instantiate(childPrefab, transform.position, Quaternion.identity);
            go.transform.SetParent(transform);
        }

        currentChildCount = childCount;
    }
}