Unity中Bandit预制体定时生成及层级删除后无法生成问题
Bandit预制体生成问题解决指南
问题1:生成数量翻倍
原因
你把带生成逻辑的Enemy脚本挂在了两个Bandit对象上,每个对象的Update方法都会独立执行生成判断,到时间两个对象同时生成新Bandit,导致数量翻倍。
解决方法
把生成逻辑和敌人移动逻辑拆分,单独用一个生成器对象负责生成:
- 在场景中创建空对象,命名为
EnemySpawner - 编写专门的生成脚本挂到该对象上,生成逻辑只在这个对象上运行
问题2:删除Bandit实例后停止生成
原因
原来的生成逻辑写在Bandit实例的脚本里,删除实例后脚本也被销毁,自然无法继续生成。
解决方法
用独立的EnemySpawner对象负责生成(同问题1的解决步骤),这个对象始终在场景中,不受Bandit实例删除的影响。
问题3:预制体无法调用player引用
原因
预制体在项目视图中,无法直接引用场景里的Player对象,运行时实例化后如果没赋值,player字段会为空。
解决方法
两种可选方案:
- 在Enemy脚本的
Start方法中自动查找Player(推荐给Player加标签) - 在Spawner生成Enemy实例后,手动给它的
player字段赋值
修改后的完整代码
Enemy.cs(仅负责敌人移动追踪)
public class Enemy : MonoBehaviour { public Transform player; // 玩家引用 public float speed = 3f; // 移动速度 void Start() { // 自动查找带Player标签的对象,避免预制体无引用问题 if (player == null) { var playerObj = GameObject.FindGameObjectWithTag("Player"); if (playerObj != null) { player = playerObj.transform; } } } void Update() { // 没有找到玩家时不执行移动逻辑 if (player == null) return; // 计算朝向玩家的方向 Vector3 direction = (player.position - transform.position).normalized; // 向玩家移动 transform.position += direction * speed * Time.deltaTime; // 看向玩家 transform.LookAt(player); } }
EnemySpawner.cs(仅负责生成预制体)
public class EnemySpawner : MonoBehaviour { public GameObject banditPrefab; // 拖拽Bandit预制体到此处 public float spawnInterval = 10f; // 生成间隔(秒) private float timer = 0f; void Update() { timer += Time.deltaTime; if (timer >= spawnInterval) { // 生成随机位置 Vector3 randomPos = new Vector3(Random.Range(0f, 119.1f), -0.001f, Random.Range(0f, 99.3f)); // 实例化预制体 Instantiate(banditPrefab, randomPos, Quaternion.identity); // 重置计时器 timer = 0f; } } }
操作步骤
- 给场景中的Player对象添加
Player标签(Inspector面板顶部标签下拉选"Add Tag..."创建) - 把Bandit预制体上的
Enemy脚本替换为上面修改后的版本 - 创建空对象
EnemySpawner,挂载EnemySpawner脚本,并将Bandit预制体拖拽到脚本的banditPrefab字段 - 删除场景中原来的两个Bandit对象,运行游戏后Spawner会自动生成第一个Bandit
内容的提问来源于stack exchange,提问作者Romy Lambrechts
相关产品推荐
相关产品推荐

