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

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;
    }
}

解决方案

核心思路是维护已生成的背景实例列表,检测并销毁超出玩家视野范围的旧实例,具体实现步骤如下:

  1. 添加实例跟踪列表
    在TileSpawner类中新增一个列表,用于保存所有生成的背景实例,方便后续管理:
private List<GameObject> spawnedPlots = new List<GameObject>();
  1. 修改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();
}
  1. 实现销毁旧实例的方法
    根据玩家当前位置(假设玩家沿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);
        }
    }
}
  1. 可选:定期检查清理
    如果BoxCollider触发频率较低,可在Update中每帧或定时调用销毁方法,确保旧实例及时被清理:
void Update()
{
    // 每帧检查一次,也可用InvokeRepeating设置定时检查
    DestroyOldPlots();
}

注意事项

  • 给玩家对象添加Player标签,或在Inspector中给TileSpawner添加一个public GameObject player变量并赋值,避免使用FindGameObjectWithTag带来的性能问题。
  • 根据游戏实际视野范围和地块大小,调整destroyThreshold的数值,确保旧实例完全离开屏幕后再销毁。

内容的提问来源于stack exchange,提问作者CodeConfusion

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 23:20:29