unity中關(guān)于刪除父物體下所有子物體,可以直接通過如下方式實(shí)現(xiàn):
public void DeleteItem()
{
for (int i = 0; i < transform.childCount; i++)
{
Destroy(transform.GetChild(i).gameObject);
}
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.H))
{
DeleteItem();
}
}
或者將所有子物體存入一個(gè)List,再進(jìn)行刪除,如下:
public List<GameObject> itemList = new List<GameObject>();
private void Awake()
{
Init();
}
public void Init()
{
for (int i = 0; i < transform.childCount; i++)
{
itemList.Add(transform.GetChild(i).gameObject);
}
}
public void DeleteItem()
{
for (int i = 0; i < itemList.Count; i++)
{
Destroy(itemList[i]);
}
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.H))
{
DeleteItem();
}
}
上述兩種方式,將代碼掛載在父物體上,運(yùn)行中按下H均可實(shí)現(xiàn)效果。
但是上述方法均會(huì)出現(xiàn)一個(gè)問題,在我們刪除完成之后去獲取父物體子物體的個(gè)數(shù),子物體數(shù)沒有發(fā)生改變,如下所示:
public void DeleteItem()
{
for (int i = 0; i < itemList.Count; i++)
{
Destroy(itemList[i]);
}
Debug.Log(transform.childCount);
}
以第二種方式為例,打印出結(jié)果如下:

image.png

image.png
可以發(fā)現(xiàn),打印出子物體數(shù)量并沒有改變, 原本推測(cè)原因是我們通過Destroy去刪除時(shí),此時(shí)GC沒有調(diào)用,然后通過手動(dòng)調(diào)用GC方式測(cè)試發(fā)現(xiàn)結(jié)果依舊沒有改變,再次查閱資料并進(jìn)行測(cè)試,發(fā)現(xiàn)原因?yàn)镈estory與DestroyImmediate的運(yùn)行方式有所不同,不同點(diǎn)如下(直接Copy過來了https://www.csdn.net/tags/MtjaQgysNzc2OC1ibG9n.html):
Destroy(異步銷毀):使用Destroy刪除游戲物體,游戲物體并不會(huì)立即被刪除,而是異步執(zhí)行的,不會(huì)影響主線程的執(zhí)行,說白了,就是它另外開一條道去執(zhí)行了;該函數(shù)給物體加了一個(gè)標(biāo)識(shí)符,物體還在內(nèi)存中,在下一幀時(shí)才銷毀并從內(nèi)存中移除。
DestroyImmediate:立即銷毀物體并移除內(nèi)存。使用DestroyImmediate刪除游戲物體,游戲物體立即被刪除,代碼順序執(zhí)行,影響主線程的執(zhí)行
如果是需要實(shí)時(shí)去改變子物體數(shù)量,可以用DestroyImmediate:
public void DeleteItem()
{
for (int i = 0; i < itemList.Count; i++)
{
//Destroy(itemList[i]);
DestroyImmediate(itemList[i]);
}
Debug.Log(transform.childCount);
}
此時(shí)刪除后,子物體數(shù)量為0:

image.png