Unity中CharacterController控制敌人调用Move方法无法移动
问题原因&修复方案
你的敌人完全无法移动是几个核心逻辑错误叠加导致的,按优先级排序:
- 协程未正确启动:直接调用
Dash_Attack()不会执行协程内的逻辑,Unity中启动协程必须使用StartCoroutine()方法包裹,你当前的写法只会生成一个枚举器对象,协程里的循环代码完全不会运行。 - 移动方向使用错误:
Vector3.forward是世界坐标系的Z轴正方向,和敌人自身朝向无关,就算执行了LookAt转向,用世界坐标forward也不会让敌人朝着面向的玩家移动,需要替换为transform.forward表示敌人自身的正前方。 - 协程循环判定值未更新:
Dash_Attack里的distance只在协程启动时计算了一次,循环过程中永远是初始值,要么直接不进循环,要么死循环卡住逻辑。 CharacterController.Move()参数传错:该方法要求传入单帧位移增量,你直接把MoveTowards算出的目标位置当参数传入是错误用法,同时缺少Time.deltaTime做帧率无关换算,会导致速度异常。- 基础配置排查项:
- 检查Inspector面板中
controller字段是否已经拖拽赋值了物体上的CharacterController组件,未赋值会触发空引用,移动逻辑完全不执行 - 检查CharacterController的碰撞体参数,确认没有卡进地面、和静态碰撞体穿模,碰撞被拦截时也会出现无法位移的情况
- 检查序列化的
speed值是否被误设为0
- 检查Inspector面板中
修正后的关键代码
- 协程调用逻辑修正
else if (distance < attack2dist) { if (attack2cooldown < 0) { transform.LookAt(playertarget); weapon.SetTrigger("JETSTREAMSAM"); Hand.SetTrigger("JETSTREAMSAM"); // 启动协程必须调用StartCoroutine StartCoroutine(Dash_Attack()); attack2cooldown = attack2CD; } }
- 常规追击移动逻辑修正
else { // 用transform.forward获取敌人自身的正前方方向 controller.Move(transform.forward * speed * Time.deltaTime); }
- 冲刺攻击协程修正
IEnumerator Dash_Attack() { // 循环内每帧重新计算和玩家的距离,保证判定准确 while (Vector3.Distance(transform.position, playertarget.position) > 3) { // 计算指向玩家的移动方向,归一化保证移动速度恒定 Vector3 moveDir = (playertarget.position - transform.position).normalized; // 锁定Y轴位移,避免敌人上下飘 moveDir.y = 0; // 传入单帧位移量,乘deltaTime保证不同帧率下移动速度一致 controller.Move(moveDir * speed * Time.deltaTime); yield return null; } }
额外提示:你代码顶部重复写了两次using UnityEngine;,虽然不会触发报错,但可以清理掉冗余的引用。
内容的提问来源于stack exchange,提问作者Bread
相关产品推荐
相关产品推荐

