Unity中Destroy方法无法销毁GameObject实例问题求助
瓦片销毁失败问题排查
问题描述
我正在编写一个随玩家移动,在其周围动态生成和移除瓦片的脚本。后续计划用噪声算法为每个坐标匹配瓦片类型,确保玩家返回旧区域时样式一致,因此无法使用静态图像方案。
当瓦片块超出渲染范围时,我对每个grassTile GameObject实例调用Destroy()方法,但这些瓦片并未从屏幕上消失。我查阅过同类问题,确认没有误销毁GameObject以外的对象,尝试DestroyImmediate()也无效。
相关代码
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using Unity.Collections; using Unity.VisualScripting; using UnityEditor.SearchService; using UnityEngine; public class TileManager : MonoBehaviour { // Objects & Variables public int chunkRadius = 1; public int renderRadius = 1; public GameObject grassTile; public GameObject background; public GameObject player; private Vector2 playerPosition => player.transform.position; private Dictionary<Vector2, GameObject[]> chunks = new Dictionary<Vector2, GameObject[]>(); private int chunkWidth; // Unity Functions void Awake() { chunkWidth = 1 + 2 * chunkRadius; DrawChunk(GetChunkPlayerIsIn()); } void Update() { foreach(Vector2 chunk in GetChunksToDraw()){ DrawChunk(chunk); } Debug.Log($"Destroying {GetChunksToDestroy().Count} chunks"); foreach(Vector2 chunk in GetChunksToDestroy()){ DestroyChunk(chunk); } } // Private Functions private List<Vector2> GetChunksToDraw(){ List<Vector2> chunksToDraw = new List<Vector2>(); Vector2 playerChunk = GetChunkPlayerIsIn(); int minX = (int)playerChunk.x - renderRadius * chunkWidth; int maxX = (int)playerChunk.x + renderRadius * chunkWidth; int minY = (int)playerChunk.y - renderRadius * chunkWidth; int maxY = (int)playerChunk.y + renderRadius * chunkWidth; for(int x = minX; x <= maxX; x += chunkWidth){ for (int y = minY; y <= maxY; y += chunkWidth){ Vector2 center = new Vector2(x, y); if(!chunks.ContainsKey(center)){ chunksToDraw.Add(center); } } } return chunksToDraw; } private List<Vector2> GetChunksToDestroy(){ List<Vector2> chunksToDestroy = new List<Vector2>(); foreach(Vector2 chunk in chunks.Keys){ float distance = Mathf.Abs((chunk - playerPosition).magnitude); if(distance > chunkWidth){ Debug.Log($"Destroying chunk {chunk} that is {distance} away"); chunksToDestroy.Add(chunk); } } return chunksToDestroy; } private Vector2 GetChunkPlayerIsIn(){ float nearestX = Mathf.Abs(playerPosition.x) + chunkRadius / 2f; nearestX -= nearestX % chunkRadius; nearestX *= playerPosition.x > 0 ? 1 : -1; float nearestY = Mathf.Abs(playerPosition.y) + chunkRadius / 2f; nearestY -= nearestY % chunkRadius; nearestY *= playerPosition.y > 0 ? 1 : -1; return new Vector2(nearestX, nearestY); } private void DrawChunk(Vector2 center) { int minX = Mathf.FloorToInt(center.x) - chunkRadius; int maxX = Mathf.FloorToInt(center.x) + chunkRadius; int minY = Mathf.FloorToInt(center.y) - chunkRadius; int maxY = Mathf.FloorToInt(center.y) + chunkRadius; GameObject[] tiles = new GameObject[(int)Mathf.Pow(1 + 2 * chunkRadius, 2)]; for(int x = minX; x <= maxX; x++){ for(int y = minY; y <= maxY; y++){ GameObject tile = Instantiate(grassTile, background.transform); tile.transform.position = new Vector2(x, y); tiles.Append(tile); } } chunks.Add(center, tiles); } private void DestroyChunk(Vector2 chunk) { for(int i = 0; i < chunks[chunk].Count(); i++){ Destroy(chunks[chunk][i]); } chunks.Remove(chunk); } }
调试更新
感谢各位评论!提问后我做了更多调试,发现grassTile预制体实例添加到数组后变为null。我编写了极简代码复现该问题:
// Objects & Variables public static TerrainManager instance; public GameObject grassTilePrefab; private GameObject[] grassTiles = new GameObject[1]; private int lifeTime = 100; // Unity Functions void Start(){ if (instance == null) instance = this; else Destroy(gameObject); grassTiles.Append(Instantiate(grassTilePrefab)); } void Update(){ --lifeTime; if(lifeTime <= 0){ Destroy(grassTiles[0]); } }
运行这段代码时,grassTilePrefab会被实例化,但永远不会消失,即使取消单例模式也无效。
而以下代码可以正确销毁grassTile游戏对象:
// Objects & Variables public static TerrainManager instance; public GameObject grassTilePrefab; private GameObject grassTile; private int lifeTime = 100; // Unity Functions void Start(){ if (instance == null) instance = this; else Destroy(gameObject); grassTile = Instantiate(grassTilePrefab); } void Update(){ --lifeTime; if(lifeTime <= 0){ Destroy(grassTile); } }
内容的提问来源于stack exchange,提问作者Spadonka
相关产品推荐
相关产品推荐

