You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中Transform.GetChild()行为异常:删除子物体后对象仍存在

问题解决思路

核心问题分析

你的代码存在两个关键问题,导致删除后物体看似“仍然存在”:

  1. 索引错位:先执行planets.RemoveAt(item)再销毁物体,会导致后续通过transform.GetChild(item)获取的物体并非你原本要删除的目标——planets列表长度已变,但Transform的子物体在当前帧还未被移除,索引对应关系彻底混乱。
  2. 遍历范围错误:打印日志时用初始的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 13:15:28