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

Unity中友方AI选择新目标时随机停止移动问题求助

问题分析与解决办法

核心原因

你的友方AI随机停止移动的问题,根源在于目标引用失效未被及时检测和选目标时可能选中已销毁/待销毁的敌人:

  1. 敌人被摧毁时,currentTarget指向的Transform会延迟到帧末才变为null,此之前Update里的currentTarget != null判断仍为true,AI试图向不存在的目标移动,表现为停止;
  2. FindGameObjectsWithTag("Enemy")可能返回已标记销毁但未完成清理的敌人,选中这类目标后,下一帧引用会直接失效,AI失去目标停止;
  3. 若AI攻击濒死敌人,造成伤害后敌人立即销毁,但FindNewTarget刚好选中这个即将消失的敌人,会触发后续目标失效。

解决步骤

1. 实时校验目标有效性

在Update中增加目标对象的有效性检查,确保AI不会向无效目标移动,且失效时立即重新找目标:

private void Update()
{
    // 校验目标是否存在且活跃
    if (currentTarget != null && currentTarget.gameObject != null && currentTarget.gameObject.activeInHierarchy)
    {
        Vector2 direction = currentTarget.position - transform.position;
        Vector2 newPosition = Vector2.MoveTowards(transform.position, currentTarget.position, moveSpeed * Time.deltaTime);
        transform.position = newPosition;
    }
    // 目标失效时自动重新寻找
    else
    {
        FindNewTarget();
    }
}

2. 筛选活跃敌人再选目标

修改FindInitialTarget和FindNewTarget,只从活跃的敌人中筛选目标,避免选中已销毁对象:

private void FindInitialTarget()
{
    GameObject[] enemies = GameObject.FindGameObjectsWithTag("Enemy");
    List<GameObject> activeEnemies = new List<GameObject>();
    
    // 过滤出存在且活跃的敌人
    foreach (GameObject enemy in enemies)
    {
        if (enemy != null && enemy.activeInHierarchy)
        {
            activeEnemies.Add(enemy);
        }
    }

    if (activeEnemies.Count > 0)
    {
        float closestDistance = Mathf.Infinity;
        foreach (GameObject enemy in activeEnemies)
        {
            float distance = Vector3.Distance(transform.position, enemy.transform.position);
            if (distance < closestDistance)
            {
                closestDistance = distance;
                currentTarget = enemy.transform;
            }
        }
    }
    else
    {
        currentTarget = null;
    }
}

private void FindNewTarget()
{
    GameObject[] enemies = GameObject.FindGameObjectsWithTag("Enemy");
    List<GameObject> activeEnemies = new List<GameObject>();
    
    foreach (GameObject enemy in enemies)
    {
        if (enemy != null && enemy.activeInHierarchy)
        {
            activeEnemies.Add(enemy);
        }
    }

    if (activeEnemies.Count > 0)
    {
        int randomIndex = Random.Range(0, activeEnemies.Count);
        currentTarget = activeEnemies[randomIndex].transform; 
        Debug.Log("New Target Chosen");
    }
    else
    {
        currentTarget = null;
    }
}

3. 敌人死亡时主动通知AI更新(可选)

在敌人的HealthDamage脚本中,当敌人死亡时主动通知持有自身为目标的AI更新,避免无效引用残留:

public void TakeDamage(int damage)
{
    currentHealth -= damage;
    if (currentHealth <= 0)
    {
        // 通知所有以当前敌人为目标的AI更换目标
        FriendlyAI[] friendlyAIs = FindObjectsOfType<FriendlyAI>();
        foreach (FriendlyAI ai in friendlyAIs)
        {
            if (ai.currentTarget == transform)
            {
                ai.FindNewTarget();
            }
        }
        Destroy(gameObject);
    }
}

额外建议

  • 避免频繁调用FindGameObjectsWithTag,可通过对象池或事件系统维护敌人列表,提升性能;
  • 无目标时可添加待机逻辑(如原地巡逻),让AI行为更自然。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 22:53:08