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

Unity如何实现敌人与玩家碰撞后短暂停止追逐的功能?

Unity敌人碰撞玩家后停顿实现方案(基于Invoke方法)

第一步:新增必要变量

在原有代码的Logic变量区域新增2个变量,方便后续控制停顿逻辑:

// 碰撞玩家后的停顿时长,可直接在Inspector面板调整数值
public float stunDuration = 1f;
// 控制敌人是否可以移动的开关
private bool canMove = true;

第二步:添加停顿恢复方法

新增独立的恢复方法,专门给Invoke延时调用:

private void RecoverFromStun()
{
    canMove = true;
    // 停顿结束后恢复追逐状态
    chasing = true;
}

第三步:修改碰撞检测逻辑

找到碰撞检测中判定碰到玩家的代码块,新增停顿触发逻辑:

if(hits[i].tag == "Fighter" && hits[i].name == "Player"){
    collidingWithPlayer = true;
    // 只有当前处于可移动状态才触发停顿,避免重复调用Invoke
    if(canMove)
    {
        canMove = false;
        chasing = false;
        // 延时stunDuration秒后调用恢复方法
        Invoke(nameof(RecoverFromStun), stunDuration);
    }
}

第四步:修改移动逻辑

在所有调用UpdateMotor的位置新增canMove判断,只有处于可移动状态时才执行移动逻辑。

额外修复原有代码的已知错误

  1. 你标注的空引用报错是因为声明了hitbox变量但调用时用了未定义的boxCollider,把boxCollider.OverlapCollider(filter, hits);改为hitbox.OverlapCollider(filter, hits);即可
  2. 删除if (hits[i] == null)后面多余的反斜杠,避免语法报错

完整修改后代码

// Experience
public int xpValue = 1;

//Particle system
public GameObject effect;

// Logic
public float triggerLength = 1;
public float chaseLength = 5;
public bool chasing;
public bool collidingWithPlayer;
// 新增:碰撞玩家后的停顿时长
public float stunDuration = 1f;
private Transform playerTransform;
private Vector3 startingPosition;
// 新增:控制敌人是否可移动
private bool canMove = true;

// Hitbox
public ContactFilter2D filter;
private BoxCollider2D hitbox;
private Collider2D[] hits = new Collider2D[10];

protected override void Start()
{
    base.Start();
    playerTransform = GameManager.instance.player.transform;
    startingPosition = transform.position;
    hitbox = transform.GetChild(0).GetComponent<BoxCollider2D>();
}

// 新增:停顿恢复方法
private void RecoverFromStun()
{
    canMove = true;
    chasing = true;
}

protected void FixedUpdate(){
    //Is the player in range?
    if(Vector3.Distance(playerTransform.position, startingPosition) < chaseLength)
    {
        if(Vector3.Distance(playerTransform.position, startingPosition) < triggerLength)
        chasing = true;

        if (chasing){
            if(!collidingWithPlayer && canMove){
                UpdateMotor((playerTransform.position - transform.position).normalized);
            }
        }
        else{
            if(canMove)
            {
                UpdateMotor(startingPosition - transform.position);
            }
        }
    }
    else{
        if(canMove)
        {
            UpdateMotor(startingPosition - transform.position);
        }
        chasing = false;
    }

    //Check for overlap
    collidingWithPlayer = false;
    // 修复空引用报错
    hitbox.OverlapCollider(filter, hits);
    for (int i = 0; i < hits.Length; i++)
    {
        // 修复语法错误,删除多余反斜杠
        if (hits[i] == null)
            continue;

        if(hits[i].tag == "Fighter" && hits[i].name == "Player"){
            collidingWithPlayer = true;
            // 新增碰撞停顿逻辑
            if(canMove)
            {
                canMove = false;
                chasing = false;
                Invoke(nameof(RecoverFromStun), stunDuration);
            }
        }

        //this array is not cleaned up, so we do it ourself
        hits[i] = null;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 21:54:02