Unity中Transform.GetChild()行为异常:删除子物体后对象仍存在
问题解决思路
核心问题分析
你的代码存在两个关键问题,导致删除后物体看似“仍然存在”:
- 索引错位:先执行
planets.RemoveAt(item)再销毁物体,会导致后续通过transform.GetChild(item)获取的物体并非你原本要删除的目标——planets列表长度已变,但Transform的子物体在当前帧还未被移除,索引对应关系彻底混乱。 - 遍历范围错误:打印日志时用初始的
startPlanetCount(4)作为循环上限,删除后Transform子物体数量已减少,但当前帧内被标记销毁的物体还未从子列表中移除,导致你误以为物体没被删除。
修正后的代码
IEnumerator DeletePlanet(int item) { yield return new WaitForSeconds(5); // 先获取要删除的物体引用,彻底避免索引错位问题 GameObject targetPlanet = transform.GetChild(item).gameObject; // 从列表移除目标 planets.RemoveAt(item); // 执行销毁 Destroy(targetPlanet); // 可选:等待一帧,让Unity完成物体销毁操作,确保Transform子列表更新 yield return null; // 直接用planets列表的引用更新位置,不再依赖Transform索引 for (int i = 0; i < planets.Count; i++) { UpdatePositions(planets[i].GetComponent<RectTransform>(), i); } // 用当前Transform子物体数量遍历,而非初始值 for (int i = 0; i < transform.childCount; i++) { print(transform.GetChild(i).gameObject.GetComponent<RectTransform>().anchoredPosition); } }
额外说明
- Unity的
Destroy()是延迟执行的:调用后物体不会立即从Hierarchy中消失,会在下一帧完成真正销毁。如果是编辑模式下需要立即移除,可改用DestroyImmediate(),但运行时不推荐使用。 - 建议让
planets列表直接存储子物体的引用:全程不需要通过transform.GetChild(i)获取物体,彻底规避索引不匹配的风险。
内容的提问来源于stack exchange,提问作者Smile3329
相关产品推荐
相关产品推荐

