2D平台游戏敌人左右移动脚本失效:射线检测后停止移动
2D平台敌人移动失效问题排查与修复
核心问题分析
- 射线方向错误:你使用的
new Vector3(-9, -3.5f, 0)不是单位向量,Physics2D.Raycast的方向参数需要单位向量,否则实际检测距离是设置的2乘以向量模长(该向量模长约9.66),相当于检测了近20单位的距离,完全不符合预期。应该用水平方向单位向量,比如Vector2.left/Vector2.right,若要检测敌人脚下前方的墙体,调整射线起点而非方向向量。 - 状态覆盖逻辑错误:第二个左射线检测的
if语句会完全覆盖第一个右射线检测设置的moving状态。比如即使右射线检测到可移动并设置MovingToRight,紧接着左射线的判断会重新赋值moving,若左射线未检测到碰撞,就会把状态改成Idle,这是敌人停止移动的核心原因。 - while循环误用:
Update每一帧执行一次,你用while循环会在单帧内重复执行移动逻辑直到条件不满足,直接导致帧卡住,且return会终止后续逻辑。这里应该用if判断,每一帧执行一次移动即可。 - 初始状态未处理:第一次射线检测前(前1秒),
raycastHitLeft和raycastHitRight的collider为null,敌人会处于Idle状态,建议给敌人设置初始移动方向。
修正后的代码
private enum Moving { MovingToRight, MovingToLeft, Idle } // 给敌人设置初始移动方向 private Moving moving = Moving.MovingToRight; private float timer; // 可调整的移动速度 public float moveSpeed = 2f; // 射线检测的偏移量,将射线起点移到敌人前方脚下 public Vector2 rayOffset = new Vector2(0, -1f); // 射线检测距离 public float rayDistance = 2f; private void Update() { timer += Time.deltaTime; if (timer > 1f) { Debug.Log("Raycast fired!"); // 计算射线起点:敌人位置 + 偏移量 Vector2 rayStart = (Vector2)transform.position + rayOffset; // 用单位向量作为方向,检测左侧墙体 RaycastHit2D raycastHitLeft = Physics2D.Raycast(rayStart, Vector2.left, rayDistance); // 检测右侧墙体 RaycastHit2D raycastHitRight = Physics2D.Raycast(rayStart, Vector2.right, rayDistance); timer = 0; // 根据当前移动方向判断是否需要转向 if (moving == Moving.MovingToRight) { // 向右移动时,前方检测到墙体则切换方向 if (raycastHitRight.collider != null) { moving = Moving.MovingToLeft; } } else if (moving == Moving.MovingToLeft) { // 向左移动时,前方检测到墙体则切换方向 if (raycastHitLeft.collider != null) { moving = Moving.MovingToRight; } } } // 处理每一帧的移动逻辑 if (moving == Moving.MovingToRight) { transform.position += Vector3.right * moveSpeed * Time.deltaTime; } else if (moving == Moving.MovingToLeft) { transform.position += Vector3.left * moveSpeed * Time.deltaTime; } }
额外说明
- 新增
moveSpeed变量方便调整移动速度,rayOffset用来适配敌人的碰撞体位置,确保射线检测到正确的墙体。 - 调整射线检测逻辑:根据当前移动方向只检测前方的墙体,避免状态被覆盖,敌人只会在当前移动方向遇到障碍时才转向。
- 移除错误的
while循环,改用if判断符合Unity帧更新逻辑,避免游戏卡顿。
内容的提问来源于stack exchange,提问作者Svak
相关产品推荐
相关产品推荐

