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() { } }
问题根源
- 协程终止后无法自动重启:当
treeAmount达到上限,canSpawn被设为false,协程的while(canSpawn == true)循环直接退出,后续即使canSpawn改回true,协程也不会再执行。 - 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
相关产品推荐
相关产品推荐

