使用计时器Instantiate的2D对象沿路点移动时异常停止问题求助
问题根因
- 仅使用单个全局
GameObject go变量存储生成的对象,每秒新生成对象时会覆盖旧对象的引用,旧对象失去脚本控制直接停止移动 - 全局共用同一个
waypointIndex变量,所有生成的对象共享同一个路点进度,既会导致旧对象路点错乱,也会让新生成的对象无法从第一个路点开始移动 - 移动逻辑和生成逻辑耦合在同一个管理器类里,没有做对象独立逻辑拆分,只要生成多个对象必然会出现逻辑冲突
- 直接使用
position !=判断是否到达路点存在浮点精度误差,可能出现永远判定为未到达的异常
修复方案
步骤1:新建独立的敌人物理脚本WaypointInvader.cs,将移动逻辑下沉到每个生成对象自身,每个对象独立维护自己的路点进度
using UnityEngine; public class WaypointInvader : MonoBehaviour { private Transform[] _waypoints; // 当前对象独立的路点索引 private int _currentWaypointIndex; public float moveSpeed = 5f; // 生成后调用,传入路点配置完成初始化 public void Init(Transform[] waypoints) { _waypoints = waypoints; _currentWaypointIndex = 0; } void Update() { if (_waypoints == null || _waypoints.Length == 0) return; Vector3 targetPos = _waypoints[_currentWaypointIndex].position; transform.position = Vector3.MoveTowards(transform.position, targetPos, moveSpeed * Time.deltaTime); // 用距离判断替代等于判断,避免浮点精度问题 if (Vector3.Distance(transform.position, targetPos) < 0.01f) { // 取余运算简化索引溢出归零逻辑 _currentWaypointIndex = (_currentWaypointIndex + 1) % _waypoints.Length; } } }
步骤2:修改原管理器脚本,仅保留定时生成逻辑,不再处理对象移动
using UnityEngine; public class WaypointTest : MonoBehaviour { [SerializeField] private Transform[] waypoints; public GameObject waypointInvaderPrefab; private int nextSpawnTime = 1; public float invaderSpeed = 5f; void Update() { if (Time.time >= nextSpawnTime) { nextSpawnTime = Mathf.FloorToInt(Time.time) + 1; // 生成新对象 GameObject newInvader = Instantiate(waypointInvaderPrefab, transform.position, transform.rotation); // 为新对象初始化路点和速度 WaypointInvader invaderLogic = newInvader.GetComponent<WaypointInvader>(); invaderLogic.Init(waypoints); invaderLogic.moveSpeed = invaderSpeed; } } }
操作注意
提前给waypointInvader预制体挂载WaypointInvader脚本即可正常运行。
内容的提问来源于stack exchange,提问作者DJ HofteOrgel
相关产品推荐
相关产品推荐

