Unity无尽跑酷游戏中如何删除背景对象的旧实例?
解决无尽跑酷背景实例堆积问题
问题描述
我开发的无尽跑酷游戏包含一条简易道路和从Blender导入的3D背景,道路末端的Box Collider触发时能让道路向前移动(这部分功能正常),但触发生成3D背景时只会创建新实例,导致旧实例不断堆积,求删除旧背景实例的方法。
相关代码
using System.Collections; using System.Collections.Generic; using UnityEngine; public class TileSpawner : MonoBehaviour { private int initAmount = 5; private float plotsize = 10f; private float lastXPos = 15f; public List<GameObject> plots; // Start is called before the first frame update void Start() { for (int i = 0; i < initAmount; i++) { SpawnPlot(); } } // Update is called once per frame void Update() { } public void SpawnPlot() { GameObject plot = plots[Random.Range(0, plots.Count)]; float xPos = lastXPos + plotsize; Instantiate(plot, new Vector3(xPos, 51.08614f, 25.10745f), plot.transform.rotation); lastXPos += plotsize; } }
解决方案
核心思路是维护已生成的背景实例列表,检测并销毁超出玩家视野范围的旧实例,具体实现步骤如下:
- 添加实例跟踪列表
在TileSpawner类中新增一个列表,用于保存所有生成的背景实例,方便后续管理:
private List<GameObject> spawnedPlots = new List<GameObject>();
- 修改SpawnPlot方法,记录生成的实例
每次生成新背景后,将实例引用添加到跟踪列表中:
public void SpawnPlot() { GameObject plot = plots[Random.Range(0, plots.Count)]; float xPos = lastXPos + plotsize; // 保存生成的实例引用 GameObject newPlot = Instantiate(plot, new Vector3(xPos, 51.08614f, 25.10745f), plot.transform.rotation); spawnedPlots.Add(newPlot); lastXPos += plotsize; // 生成新实例后立即检查并销毁旧实例 DestroyOldPlots(); }
- 实现销毁旧实例的方法
根据玩家当前位置(假设玩家沿X轴移动),判断背景实例是否已远远落在玩家后方,满足条件则销毁实例并从列表中移除:
private void DestroyOldPlots() { // 获取玩家当前X位置(建议在Inspector中直接赋值玩家对象,避免Find的性能损耗) float playerX = GameObject.FindGameObjectWithTag("Player").transform.position.x; // 设定销毁阈值:玩家位置减去2倍地块长度,确保旧实例完全离开视野 float destroyThreshold = playerX - plotsize * 2; // 倒序遍历列表,避免删除元素时索引混乱 for (int i = spawnedPlots.Count - 1; i >= 0; i--) { GameObject plot = spawnedPlots[i]; if (plot.transform.position.x < destroyThreshold) { Destroy(plot); spawnedPlots.RemoveAt(i); } } }
- 可选:定期检查清理
如果BoxCollider触发频率较低,可在Update中每帧或定时调用销毁方法,确保旧实例及时被清理:
void Update() { // 每帧检查一次,也可用InvokeRepeating设置定时检查 DestroyOldPlots(); }
注意事项
- 给玩家对象添加
Player标签,或在Inspector中给TileSpawner添加一个public GameObject player变量并赋值,避免使用FindGameObjectWithTag带来的性能问题。 - 根据游戏实际视野范围和地块大小,调整
destroyThreshold的数值,确保旧实例完全离开屏幕后再销毁。
内容的提问来源于stack exchange,提问作者CodeConfusion
相关产品推荐
相关产品推荐

