[英]How can i destroy all the childs objects before creating new?
In this function i make a loop over the childs and destroy them. 在此功能中,我循环遍历孩子并将其销毁。 The problem is for example if i have 1 child and in the Inspector in the script i change the value of the childs from 1 to 10 then it will add 10 new childs to the one that was already exist.
问题是,例如,如果我有1个孩子,并且在脚本的Inspector中,我将孩子的值从1更改为10,那么它将为已经存在的孩子添加10个新孩子。 So i have now 11. And then if i change the value from 10 to 100 i will have 111 and if i change back to 1 then i will have 112.
所以我现在有11。然后,如果我将值从10更改为100,我将拥有111,如果我更改为1,那么我将拥有112。
What i want it to do while the game is running if i change the value first destroy all the childs then make the new once according to the last changed value. 如果我更改值,则我想在游戏运行时做什么,请先销毁所有子项,然后根据最后更改的值重新创建一次。 So if the value when i'm runinng the game is 10 and i change it to 100 first delete the 10 then add new 100. If i change from 10 to 1 first delete the 10 then add 1.
因此,如果我在运行游戏时将值更改为10,然后将其更改为100,请先删除10,然后再添加100。如果我从10更改为1,请先删除10,然后添加1。
What i want to do in general is when changing the value of _birdscount while the game is running change the number of childs. 我通常想做的是在游戏运行时更改_birdscount的值时更改子代数。
In the top of the script: 在脚本顶部:
public CameraControl cameraControl;
public Object birdPrefab;
public Transform birdParent;
private Transform cameraObj;
public Transform[] instancePoints;
public int _birdscount;
In the Start function i added a StartCoroutine: 在启动功能中,我添加了一个StartCoroutine:
void Start()
{
if( globalSettings == null )
{
settings = LoadSettings();
globalSettings = settings;
}
else
settings = globalSettings;
InstantiateBirds();
cameraControl.Enabled = !settings.showSettingsWindow;
StartCoroutine(_WatchBirdCount());
}
Then in a function that will check if the value _birdscount changed or not and destroying the childs and create new once: 然后在一个函数中,该函数将检查值_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
{
}
}
}
The InstantiateBirds() function that make the childs: I added to this function the line: 创建子项的InstantiateBirds()函数:我在该函数中添加了以下代码行:
sts.BirdsCount = prevBirdCount;
Here: 这里:
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
);
});
}
And if it's needed the InstantiateBird function: 并且如果需要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;
}
Something along these lines should do that: 遵循这些原则可以做到这一点:
public void ClearChilds(Transform parent)
{
foreach(Transform child in parent)
{
Destroy(child.gameObject);
}
}
You do have these lines in your code with a little difference: You only call Destroy
on the transform ( child
), not the gameobject ( child.gameObject
). 您的代码中确实有这些行,但有一点区别:您仅在转换(
child
)上调用Destroy
,而不在gameobject( child.gameObject
)上child.gameObject
。
EDIT: 编辑:
I wrote a little code that will update the number of children of the object the script is on according to the number of the public field ( childCount
). 我编写了一些代码,该代码将根据公共字段的数量(
childCount
)更新脚本所在的对象的孩子数量。 currentChildCount
is just for testing public (this is your prevBirdCount
). currentChildCount
仅用于测试public(这是您的prevBirdCount
)。 This script will destroy all old children first and then instantiate new ones. 该脚本将首先销毁所有老孩子,然后实例化新孩子。
For testing this code, you just need some object as parent that you place this script on and some prefab that serves as child. 为了测试此代码,您只需要一些对象(将其作为脚本的父对象)和一些用作子对象的预制件即可。 (I don't fiddle with positioning.)
(我不摆弄定位。)
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;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.