AR环境中EnemyPrefab向StationaryPrefab移动的MoveTowards失效问题
问题分析与修复方案
核心问题点
- 数组未初始化且Append无效:
enemies是GameObject[]数组,默认值为null,且数组长度固定,Append方法不会修改原数组,仅返回新数组,导致敌人实例根本没被存入集合。 - 移动逻辑仅执行一次:移动代码放在生成敌人的分支里,只有在生成敌人的那一帧才会执行一次移动,之后敌人不再移动。
- 速度未做帧率适配:
speed直接传入Vector3.MoveTowards,移动速度会受帧率影响,不同设备上移动快慢不一致。 - 日志输出错误:Unity中需用
Debug.Log而非Console.Write,后者无法在Unity控制台显示内容。
修复后的代码
using System.Collections.Generic; using UnityEngine; public class Spawner : MonoBehaviour { public GameObject enemyPrefab; public GameObject stationaryPrefab; public int maxEnemy = 5; // 改用List存储敌人,支持动态添加 private List<GameObject> enemies = new List<GameObject>(); public float timeSpawn = 3f; private float timer; public float distance = 5; // speed单位设为"单位/秒" public float speed = 1f; private void Start() { timer = timeSpawn; // 若Spawner负责实例化静止预制体,可添加以下代码(按需启用) // if (stationaryPrefab == null) // stationaryPrefab = Instantiate(stationaryPrefab, transform.position, Quaternion.identity); } private void Update() { // 处理敌人生成逻辑 timer -= Time.deltaTime; if (timer <= 0 && enemies.Count < maxEnemy) { timer = timeSpawn; Vector3 spawnPos = Random.insideUnitSphere * distance; // AR场景建议限制在XY平面,取消注释替换上方行 // Vector3 spawnPos = Random.insideUnitCircle * distance; GameObject newEnemy = Instantiate(enemyPrefab, spawnPos, Quaternion.identity, transform); enemies.Add(newEnemy); } // 每帧更新所有敌人的移动 foreach (GameObject enemyInstance in enemies) { if (enemyInstance == null) continue; // 避免敌人被销毁后空引用报错 Vector3 targetPos = stationaryPrefab.transform.position; // 乘以Time.deltaTime让速度基于时间而非帧率 enemyInstance.transform.position = Vector3.MoveTowards(enemyInstance.transform.position, targetPos, speed * Time.deltaTime); Debug.Log(enemyInstance.name + " 正在移动"); } } }
额外优化建议
- 分离移动逻辑:给EnemyPrefab单独编写
EnemyMovement脚本,负责自身向目标移动,Spawner仅专注生成逻辑,更符合Unity组件化设计:
using UnityEngine; public class EnemyMovement : MonoBehaviour { public GameObject target; public float speed = 1f; private void Update() { if (target == null) return; transform.position = Vector3.MoveTowards(transform.position, target.transform.position, speed * Time.deltaTime); } }
使用时,在Spawner生成敌人后,给敌人的EnemyMovement组件赋值target = stationaryPrefab即可。
- AR场景适配:建议用
Random.insideUnitCircle生成敌人位置,将敌人限制在XY平面,避免生成到空中或地下,提升AR体验。
内容的提问来源于stack exchange,提问作者Moon Knightly
相关产品推荐
相关产品推荐

