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

Unity中销毁树木后无法继续生成的技术问题求助

Unity树木生成异常问题

树木数量达到上限5棵时停止生成,但销毁树木使数量低于5后无法重新生成;始终保持2棵时生成正常,一旦到5就彻底停了。我尝试过修改spawnRate为0再改回1,但无效——Unity面板显示数值已变,但树木仍在生成,猜测需要重置canSpawn,但不确定是否还有其他错误。

相关脚本

1. Harvest脚本(点击销毁树木)

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

public class Harvest : MonoBehaviour
{
    public GameObject tree;
    public int treeScore;
    public void AddTreeScore()
    {
        treeScore++;
    }

    private Spawner spawnerScript;
    void Start()
    {
        spawnerScript = FindObjectOfType<Spawner>();
    }

    public void OnMouseDown()
    {
        GameObject.Destroy(tree);
        spawnerScript.treeAmount--;
        AddTreeScore();
        Debug.Log(treeScore);
    }
}

2. Spawner脚本(树木生成逻辑)

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;

public class Spawner : MonoBehaviour
{
    public GameObject tree;

    public int treeAmount;

    public float spawnRate = 1f;

    public bool canSpawn = true;

    public int maxAmount = 5;

    private IEnumerator Spawning()
    {
        WaitForSeconds wait = new WaitForSeconds(spawnRate);

        while (canSpawn == true)
        {
            yield return wait;
            
            Vector2 randomSpawnPos = new Vector2(Random.Range(-10, 11), Random.Range(-4, 5));
            Instantiate(tree, randomSpawnPos, Quaternion.identity);
            AddTreeAmount();

            if (treeAmount >= maxAmount)
            {
                canSpawn = false;
                
            }
            if( treeAmount < maxAmount)
            {
                canSpawn = true;
            }
        }
    }
    void AddTreeAmount()
    {
        treeAmount++;
    }

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

    void Update()
    {
        
    }
}

问题根源

  1. 协程终止后无法自动重启:当treeAmount达到上限,canSpawn被设为false,协程的while(canSpawn == true)循环直接退出,后续即使canSpawn改回true,协程也不会再执行。
  2. WaitForSeconds缓存失效:WaitForSeconds在协程启动时就已实例化,后续修改spawnRate不会更新等待时长,所以改数值没用。

修复方案

最优方案:调整协程逻辑,保持循环持续运行

把协程改成无限循环,内部判断生成条件,避免退出协程:

private IEnumerator Spawning()
{
    while (true) // 保持协程一直运行
    {
        yield return new WaitForSeconds(spawnRate); // 每次等待都用最新的spawnRate
        
        // 直接用treeAmount判断,去掉冗余的canSpawn变量
        if (treeAmount >= maxAmount)
        {
            continue; // 不满足条件就跳过本次生成
        }
        
        Vector2 randomSpawnPos = new Vector2(Random.Range(-10, 11), Random.Range(-4, 5));
        Instantiate(tree, randomSpawnPos, Quaternion.identity);
        treeAmount++; // 直接修改,简化逻辑
    }
}

同时可以移除canSpawn变量和AddTreeAmount方法,减少冗余代码。

备选方案:手动重启协程(效率较低)

如果不想改协程结构,可以在Spawner里加一个重启协程的方法:

private Coroutine spawnCoroutine;

void Start()
{
    spawnCoroutine = StartCoroutine(Spawning());
}

public void RestartSpawn()
{
    if (treeAmount < maxAmount && !canSpawn)
    {
        canSpawn = true;
        StopCoroutine(spawnCoroutine);
        spawnCoroutine = StartCoroutine(Spawning());
    }
}

然后在Harvest的OnMouseDown中调用:

public void OnMouseDown()
{
    GameObject.Destroy(tree);
    spawnerScript.treeAmount--;
    spawnerScript.RestartSpawn(); // 新增调用
    AddTreeScore();
    Debug.Log(treeScore);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 06:35:58