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

Unity3D C#:销毁全部陨石后如何持续生成新陨石?

问题解决:销毁陨石后无法继续生成的修复

核心问题原因

你的陨石生成停止,根本原因是**MeteoroidSpawn.cs里的预制体引用被覆盖**:
在SpawnRoutine中,你执行了meteoroid = Instantiate(meteoroid, spawnPos, Quaternion.identity);,这行代码把原本指向预制体的meteoroid变量,替换成了第一次实例化出来的陨石对象。后续循环再调用Instantiate时,传入的已经不是预制体,导致无法生成新陨石。

解决方案步骤

  1. 修复预制体引用覆盖问题:把预制体变量和实例化对象分开,避免覆盖预制体引用
  2. 优化陨石管理与销毁逻辑:用全局列表追踪所有陨石,比每次调用FindGameObjectsWithTag更高效,也能避免销毁时的潜在问题
  3. 确保飞船重置时的销毁逻辑不影响生成

修正后的代码

MeteoroidSpawn.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MeteoroidSpawn : MonoBehaviour
{
    // 单独存储预制体引用,避免被实例覆盖
    [SerializeField] 
    private GameObject meteoroidPrefab; 

    [SerializeField]
    private bool spawn = true;

    // 全局列表管理所有陨石,方便销毁和统计
    public static List<GameObject> activeMeteoroids = new List<GameObject>();

    void Start()
    {
        StartCoroutine(SpawnRoutine());
    }

    IEnumerator SpawnRoutine()
    {
        Vector2 spawnPos = Vector2.zero;
        
        while (spawn)
        {
            yield return new WaitForSeconds(1f);

            // 使用预制体实例化,不覆盖原变量
            spawnPos.x = Random.Range(-Screen.width/40, Screen.width/40);
            spawnPos.y = -Screen.height/40;
            GameObject newMeteor = Instantiate(meteoroidPrefab, spawnPos, Quaternion.identity);
            // 将新陨石加入全局列表
            activeMeteoroids.Add(newMeteor);
        }
    }
}

Meteoroid.cs

using UnityEngine;

public class Meteoroid : MonoBehaviour
{
    [SerializeField] 
    private GameObject spaceship;

    [SerializeField] 
    private float speed = 1.0f;

    [SerializeField] 
    private Rigidbody2D rb;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
    }

    void Update()
    {
        transform.position = Vector2.MoveTowards(transform.position, spaceship.transform.position, speed * Time.deltaTime);
        transform.up = spaceship.transform.position - transform.position;
    }

    private void OnCollisionEnter2D(Collision2D collision)
    {
        // 使用全局列表销毁所有陨石,效率更高
        foreach (var meteor in MeteoroidSpawn.activeMeteoroids)
        {
            Destroy(meteor);
        }
        // 清空列表
        MeteoroidSpawn.activeMeteoroids.Clear();
    }

    // 陨石被销毁时自动从列表移除
    private void OnDestroy()
    {
        MeteoroidSpawn.activeMeteoroids.Remove(gameObject);
    }
}

额外优化建议

  • 把陨石销毁的触发逻辑移到飞船的损毁处理脚本中,而不是陨石的碰撞事件里,逻辑更清晰(比如飞船被撞后,先移动到顶部,再触发销毁所有陨石)
  • 可以调整生成间隔的随机性,让游戏体验更接近原作

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 16:24:45