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

如何在不使用If语句的情况下实现带优先级的A*寻路AI系统

基于性格的AI行为重构方案

核心思路:策略模式

通过策略模式将不同性格的AI行为逻辑解耦,避免大量嵌套if语句,同时方便后续扩展新的性格类型。核心是为每种性格定义独立的行为策略类,主AI类只需根据当前性格调用对应策略的方法。

步骤1:定义AI行为策略接口

创建统一接口规范所有AI行为的核心方法:

public interface IAIPersonalityStrategy
{
    void HandleNormalState(EnemyAI enemy);
    void HandleLowHPState(EnemyAI enemy);
}

步骤2:实现各性格的策略类

针对每种性格编写对应的行为逻辑:

骄傲型(Proud)AI策略

骄傲的敌人不会求援,优先回血,即使低血量也坚持战斗到极限:

public class ProudAIStrategy : IAIPersonalityStrategy
{
    public void HandleNormalState(EnemyAI enemy)
    {
        // 正常状态下始终追击目标
        enemy.destinationSetter.target = enemy.target;
    }

    public void HandleLowHPState(EnemyAI enemy)
    {
        // 低血量时优先寻找回血点,找不到才继续战斗
        var healStation = enemy.ScanForHelp(enemy.whatIsHeal);
        enemy.destinationSetter.target = healStation ?? enemy.target;
    }
}

聪明型(Smart)AI策略

聪明的敌人会优先求援,求援失败再找回血点,最大化生存概率:

public class SmartAIStrategy : IAIPersonalityStrategy
{
    public void HandleNormalState(EnemyAI enemy)
    {
        enemy.destinationSetter.target = enemy.target;
    }

    public void HandleLowHPState(EnemyAI enemy)
    {
        if (enemy.canCallSupport)
        {
            var support = enemy.ScanForHelp(enemy.whatIsSupport);
            if (support != null)
            {
                enemy.destinationSetter.target = support;
                enemy.CallSupport();
                return;
            }
        }
        // 求援失败或无法求援时,寻找回血点
        var healStation = enemy.ScanForHelp(enemy.whatIsHeal);
        enemy.destinationSetter.target = healStation ?? enemy.target;
    }
}

愚笨型(Dumb)AI策略

愚笨的敌人逻辑简单,低血量时随机选择求援或回血,甚至可能原地不动:

public class DumbAIStrategy : IAIPersonalityStrategy
{
    private readonly System.Random _random = new System.Random();

    public void HandleNormalState(EnemyAI enemy)
    {
        // 偶尔可能忘记追击(模拟愚笨)
        if (_random.Next(10) > 2)
        {
            enemy.destinationSetter.target = enemy.target;
        }
    }

    public void HandleLowHPState(EnemyAI enemy)
    {
        int choice = _random.Next(3);
        switch (choice)
        {
            case 0:
                // 求援
                if (enemy.canCallSupport)
                {
                    var support = enemy.ScanForHelp(enemy.whatIsSupport);
                    enemy.destinationSetter.target = support ?? enemy.target;
                }
                break;
            case 1:
                // 回血
                var healStation = enemy.ScanForHelp(enemy.whatIsHeal);
                enemy.destinationSetter.target = healStation ?? enemy.target;
                break;
            case 2:
                // 原地不动
                enemy.destinationSetter.target = null;
                break;
        }
    }
}

步骤3:重构EnemyAI主类

将原有的嵌套逻辑替换为策略调用,同时修复ScanForHelp的索引越界问题:

using UnityEngine;
using Pathfinding;

public class EnemyAI : MonoBehaviour
{
    public enum Personality { Proud, Smart, Dumb }
    public Personality personality;

    public bool lowHP;
    public bool inDanger;
    public bool shouldMove;

    public bool canCallSupport = true;

    public Transform target;
    public Transform healStation;
    public Transform swarm;

    public float scanRadius;
    public float alertRadius;

    public LayerMask whatIsSupport;
    public LayerMask whatIsHeal;

    public AIDestinationSetter destinationSetter;

    private IAIPersonalityStrategy _currentStrategy;

    private void Awake()
    {
        destinationSetter = GetComponent<AIDestinationSetter>();
        // 根据初始性格设置策略
        SetPersonalityStrategy(personality);
    }

    private void Update()
    {
        if (!shouldMove) return;

        if (!lowHP)
        {
            _currentStrategy.HandleNormalState(this);
        }
        else
        {
            _currentStrategy.HandleLowHPState(this);
        }
    }

    // 切换性格策略的方法
    public void SetPersonalityStrategy(Personality newPersonality)
    {
        personality = newPersonality;
        switch (newPersonality)
        {
            case Personality.Proud:
                _currentStrategy = new ProudAIStrategy();
                break;
            case Personality.Smart:
                _currentStrategy = new SmartAIStrategy();
                break;
            case Personality.Dumb:
                _currentStrategy = new DumbAIStrategy();
                break;
        }
    }

    private void OnDrawGizmos()
    {
        Gizmos.color = Color.green;
        Gizmos.DrawWireSphere(transform.position, scanRadius);
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(transform.position, alertRadius);
    }

    // 修复后的扫描辅助方法
    public Transform ScanForHelp(LayerMask mask)
    {
        RaycastHit2D[] hits = Physics2D.CircleCastAll(transform.position, scanRadius, Vector2.right, 0.1f, mask);
        if (hits.Length == 0) return null;

        Transform closestHelp = hits[0].transform;
        float closestDistance = Vector3.Distance(transform.position, closestHelp.position);

        foreach (RaycastHit2D hit in hits)
        {
            float distance = Vector3.Distance(transform.position, hit.transform.position);
            if (distance < closestDistance)
            {
                closestDistance = distance;
                closestHelp = hit.transform;
            }
        }

        return closestHelp;
    }

    public void CallSupport()
    {
        RaycastHit2D[] hits = Physics2D.CircleCastAll(transform.position, alertRadius, Vector2.right, 0.1f, whatIsSupport);
        foreach (RaycastHit2D hit in hits)
        {
            if (hit.collider.TryGetComponent<AIDestinationSetter>(out var setter))
            {
                setter.target = target;
            }
            if (hit.collider.TryGetComponent<AIPath>(out var path))
            {
                path.canMove = true;
            }
        }
        lowHP = false;
    }
}

方案优势

  • 低耦合:每种性格的行为逻辑独立,修改或新增性格无需改动主AI类代码。
  • 可读性强:策略类命名清晰,行为逻辑一目了然,避免嵌套if的混乱。
  • 扩展性高:新增性格只需实现IAIPersonalityStrategy接口即可,符合开闭原则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 03:55:00