You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity NavMesh Agent调用Attack()后无法停止行走的问题咨询

解决Unity NavMesh Agent调用Attack()后无法停止行走的问题

问题原因分析

你当前的代码仅通过设置agent.speed = 0f尝试停止Agent,但这种方式存在两个关键问题:

  • NavMeshAgent的speed仅限制最大移动速度,已产生的速度不会瞬间清零,Agent可能会继续滑行一段距离。
  • Update方法中每帧都在设置agent.destination = player.position,这会让Agent持续尝试计算并向目标移动,即使speed设为0,导航逻辑仍在运行,导致Agent无法真正停止。

修复方案

使用NavMeshAgent的isStopped属性来完全暂停导航逻辑,同时配合速度设置,确保Agent立刻停止,并在指定时间后恢复正常移动:

  1. 在Attack()方法中,添加agent.isStopped = true来暂停Agent的导航行为。
  2. 在ResumeWalking()协程中,恢复速度的同时设置agent.isStopped = false,重启导航逻辑。
  3. 恢复速度时使用成员变量agentSpeed而非硬编码的2f,保持配置一致性。

修改后的完整代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class AiLoco3 : MonoBehaviour
{
    private Transform player;
    private NavMeshAgent agent;
    Animator animator;

    public float agentSpeed = 2f;

    void Start()
    {
        player = GameObject.FindGameObjectWithTag("Player").transform;
        agent = GetComponent<NavMeshAgent>();
        animator = GetComponent<Animator>();
        
        agent.speed = agentSpeed;
    }

    void Update()
    {
        agent.destination = player.position;
        animator.SetFloat("Speed", agent.velocity.magnitude);
    }

    public void Attack()
    {
        Debug.Log("ATTACK");
        // 暂停导航逻辑并设置速度为0
        agent.isStopped = true;
        agent.speed = 0f;

        StartCoroutine(ResumeWalking());
    }

    IEnumerator ResumeWalking()
    {
        yield return new WaitForSeconds(2);
        // 恢复速度并重启导航逻辑
        agent.speed = agentSpeed;
        agent.isStopped = false;
    }

    public void Charge()
    {
        Debug.Log("Run");
        agent.speed = 8f;
        Invoke("ChargeTime", 2.0f);
    }

    public void ChargeTime()
    {
        agent.speed = agentSpeed;
    }
}

额外优化建议

  • 如果需要让Agent在停止时立刻清零速度,可以在设置isStopped = true后,额外添加agent.velocity = Vector3.zero,避免Agent因惯性滑行。
  • 若Attack期间不需要追踪玩家位置,可以添加一个isAttacking布尔变量来控制Update中的目标设置,减少不必要的路径计算:
    private bool isAttacking;
    
    void Update()
    {
        if (!isAttacking)
        {
            agent.destination = player.position;
        }
        animator.SetFloat("Speed", agent.velocity.magnitude);
    }
    
    public void Attack()
    {
        Debug.Log("ATTACK");
        isAttacking = true;
        agent.isStopped = true;
        agent.speed = 0f;
        agent.velocity = Vector3.zero;
    
        StartCoroutine(ResumeWalking());
    }
    
    IEnumerator ResumeWalking()
    {
        yield return new WaitForSeconds(2);
        agent.speed = agentSpeed;
        agent.isStopped = false;
        isAttacking = false;
    }
    

内容的提问来源于stack exchange,提问作者Fluid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 19:30:25