Unity手动/代码删子物体差异:扫雷重生成地图相邻地雷计数失效
故障原因
核心问题来自Unity Destroy() 方法的延迟执行机制:你在GenerateNewMap中调用Destroy删除旧tile时,这些对象不会立刻从场景中移除,而是会等到当前帧渲染结束后才真正销毁。你紧接着调用GenerateMines生成新tile时,旧tile还未被清除,新旧tile的命名规则完全一致(均为「行号 列号」格式),后续代码用GameObject.Find()查找对应坐标的tile时,会优先匹配到未销毁的旧tile,你对旧tile的AdjacentMines字段做修改,不会同步到新生成的tile上,就会出现新地图相邻地雷数全为0的问题。
手动在Hierarchy面板删除对象是立刻执行销毁的,不会有残留旧对象干扰,所以操作后功能正常。
解决方案
方案1:改用DestroyImmediate立刻销毁旧对象(最快修复)
直接把删除逻辑中的Destroy替换为DestroyImmediate,让旧tile被立刻清除,后续生成新tile时不会出现重名干扰。该方案修改量极小,适合tile数量不多的扫雷场景:
public void GenerateNewMap() { // 立刻销毁所有旧tiles foreach (Transform child in map.transform) { DestroyImmediate(child.gameObject); } MineIds_.Clear(); GenerateMines(); }
方案2:缓存tile列表,弃用GameObject.Find(最佳实践)
GameObject.Find本身性能差、易受重名干扰,更规范的做法是在生成tile时就把所有实例存入缓存列表,后续查找直接从列表取,完全不受旧对象影响:
- 先在类中定义全局缓存变量:
private List<GameObject> allTiles = new List<GameObject>();
- 生成tile时存入缓存:
// 在生成tile的循环中添加 allTiles.Add(tile_);
- 统计相邻地雷时直接从缓存取,不需要调用
GameObject.Find:
// 统计循环中替换查找逻辑 GameObject currentTile = allTiles[i];
- 每次生成新地图前清空缓存列表。
内容的提问来源于stack exchange,提问作者Milán Karvalics
相关产品推荐
相关产品推荐

