Unity中敌人碰撞玩家后如何停止向玩家移动?
解决敌人碰撞玩家后仍持续向玩家移动的问题
问题分析
你的核心需求是敌人与玩家碰撞后,暂停向玩家的追踪移动,给玩家留出被击退的时间,避免连续攻击。现有代码的问题在于:
- 攻击状态
isAttacking仅持续1秒,结束后敌人会立刻回到追踪逻辑 - 直接修改
transform.position来移动,导致修改Rigidbody velocity或speed的操作无效(因为移动逻辑完全绕开了物理组件) - 原代码中
Mathf.Sign的参数存在语法错误,可能导致方向计算异常
解决方案
新增专门的状态变量控制碰撞后的移动暂停,调整移动触发条件,确保碰撞后敌人停止追踪玩家,直到玩家完成击退动作。
修改后的完整代码:
// 新增状态:标记是否需要等待玩家完成击退 private bool isWaitingForPlayerKnockback; // 可根据玩家击退动画时长调整等待时间 private float knockbackWaitDuration = 0.6f; void Update() { float distFromPlayer = Mathf.Abs(player.transform.position.x - transform.position.x); // 移动条件新增:不在等待玩家击退的状态中 if (!isKnockback && !isAttacking && !isWaitingForPlayerKnockback) { // 修正原代码的语法错误:移除多余分号 float direction = Mathf.Sign(player.transform.position.x - transform.position.x); Vector2 movePos = new Vector2( transform.position.x + direction * speed * Time.deltaTime, transform.position.y ); transform.position = movePos; } } private void OnTriggerEnter2D(Collider2D collision) { if (collision.gameObject.tag == "Player") { Attack(); // 触发攻击同时启动击退等待协程 StartCoroutine(WaitForPlayerKnockback()); } } IEnumerator Attack() { isAttacking = true; yield return new WaitForSeconds(1); isAttacking = false; } // 新增协程:控制碰撞后的移动暂停时长 IEnumerator WaitForPlayerKnockback() { isWaitingForPlayerKnockback = true; yield return new WaitForSeconds(knockbackWaitDuration); isWaitingForPlayerKnockback = false; }
关键改动说明
- 新增状态变量
isWaitingForPlayerKnockback:专门标记碰撞后需要暂停追踪的状态,和攻击、击退状态区分开,避免状态冲突 - 修正语法错误:移除
Mathf.Sign参数中的多余分号,确保方向计算正常 - 调整移动触发条件:只有当三个状态都为false时,敌人才会继续向玩家移动
- 新增
WaitForPlayerKnockback协程:在碰撞触发攻击时启动,控制暂停移动的时长,可根据玩家实际击退动画时长调整knockbackWaitDuration
额外优化建议
- 如果玩家击退是通过物理力实现的,建议将敌人移动逻辑改为通过Rigidbody控制(比如
rb.velocity = new Vector2(direction * speed, rb.velocity.y)),这样物理相关操作会更有效 - 可在
OnTriggerExit2D中提前终止WaitForPlayerKnockback协程,当玩家离开敌人攻击范围时,立刻恢复追踪
内容的提问来源于stack exchange,提问作者Krok
相关产品推荐
相关产品推荐

