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

Unity敌人AI故障:添加停止追击代码后完全停止追击

解决敌人追击突然失效的问题

嘿,我帮你揪出问题根源了——你的代码里有几个容易忽略的小错误,直接导致敌人完全停止追击,咱们一个个说:

1. 致命的拼写错误

在EnemyAgro脚本里,你定义的生命值变量是curentHealth(少了个字母'r'),但在Update的停止追击判断里却写了currentHealth <= 0。这会让Unity把currentHealth当成一个未初始化的新变量,默认值是0,所以这个条件永远为真!不管玩家是不是在仇恨范围内、敌人活没活着,都会触发StopChasingPlayer(),这就是敌人直接躺平的核心原因。

2. EnemyHealth组件获取方式完全错了

在EnemyAgro的Start方法里,你写了:

enemyHealth = enemyHealth.GetComponent<EnemyHealth>();

这相当于用一个还没赋值的null变量去调用GetComponent,结果enemyHealth还是null,根本拿不到敌人的生命值数据。正确的做法分两种:

  • 如果EnemyHealth和EnemyAgro脚本挂在同一个敌人GameObject上,直接这么写:
    enemyHealth = GetComponent<EnemyHealth>();
    
  • 如果你的Enemy变量是在Inspector里拖拽赋值的敌人对象,就用这个变量获取组件:
    enemyHealth = Enemy.GetComponent<EnemyHealth>();
    

3. 生命值没有实时同步

就算前面两个问题修复了,你现在的curentHealth只在Start里赋值了一次,之后敌人掉血时,这个变量不会自动同步EnemyHealth里的真实生命值。敌人死了它还是初始的20,根本触发不了停止追击的条件。所以得在Update里实时拉取最新的生命值,或者用事件监听(更高效)。


修复后的完整EnemyAgro脚本

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

public class EnemyAgro : MonoBehaviour {
    public GameObject Enemy; // 不需要的话可以删掉,要留的话记得在Inspector赋值
    private EnemyHealth enemyHealth;
    private int currentHealth; // 修正拼写错误!
    [SerializeField] Transform player;
    [SerializeField] float agroRange;
    [SerializeField] float moveSpeed;
    public Rigidbody2D rb2d;

    public void Start() {
        // 修复组件获取:假设两个脚本在同一个对象上
        enemyHealth = GetComponent<EnemyHealth>();
        // 如果用Enemy变量,就替换成下面这行:
        // enemyHealth = Enemy.GetComponent<EnemyHealth>();
        
        currentHealth = enemyHealth.health;
        rb2d = GetComponent<Rigidbody2D>();
    }

    void Update() {
        float distToPlayer = Vector2.Distance(transform.position, player.position);
        
        // 实时同步生命值,确保拿到最新状态
        currentHealth = enemyHealth.health;

        // 优化判断逻辑:只有玩家在范围内且敌人活着,才追击
        if(distToPlayer < agroRange && currentHealth > 0){
            ChasePlayer();
        } else {
            Debug.Log("Chase Stopped");
            StopChasingPlayer();
        }
    }

    private void ChasePlayer(){
        if(transform.position.x < player.position.x){
            rb2d.velocity = new Vector2(moveSpeed,0);
            transform.localScale = new Vector2(1,1);
        } else if(transform.position.x > player.position.x){
            rb2d.velocity = new Vector2(-moveSpeed,0);
            transform.localScale = new Vector2(-1,1);
        }
    }

    public void StopChasingPlayer(){
        rb2d.velocity = Vector2.zero;
    }
}

额外优化建议(可选)

如果你想让代码更高效,可以用EnemyHealth里的OnHealthChanged事件来监听生命值变化,不用在Update里每帧都拉取:
在EnemyAgro的Start方法里加一行:

enemyHealth.OnHealthChanged += EnemyHealth_OnHealthChanged;

然后添加事件处理方法:

private void EnemyHealth_OnHealthChanged(object sender, System.EventArgs e){
    currentHealth = enemyHealth.health;
}

记得在脚本销毁时移除监听,避免内存泄漏:

private void OnDestroy(){
    if(enemyHealth != null){
        enemyHealth.OnHealthChanged -= EnemyHealth_OnHealthChanged;
    }
}

另外,你的EnemyHealth脚本里有重复的Health()和GetHealth()方法,建议删掉其中一个,避免自己混淆。

这样修复后,敌人就会正常工作:玩家在仇恨范围内时追击,离开范围或者死亡后立刻停止。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 12:02:28