Game_Num_Basics_And_Calc

Utility AI 决策系统 (Utility AI Decision System)

[!IMPORTANT] 核心理念: AI 不应该只是“处于”某种状态 (State),而应该根据当前环境评估所有可能行为的“效用” (Utility),并选择最优解。

Utility AI (效用 AI) 是一种基于评分 (Scoring) 的决策架构。与传统的 FSM (有限状态机) 或行为树相比,它在处理模糊逻辑和多目标权衡时表现出极高的涌现性 (Emergent Behavior)。


1. 为什么选择 Utility AI? (Why Utility AI?)

FSM vs Utility AI

适用场景


2. 数学模型 (The Mathematical Model)

Utility AI 的核心是将所有“考虑因素” (Considerations) 归一化为 0.01.0 之间的浮点数。

2.1 响应曲线 (Response Curves)

输入通常是原始游戏数据 (距离、血量、时间),输出是 效用 (Utility)。我们需要通过曲线来映射这种关系。

曲线类型 形状描述 典型应用
Linear (线性) /\ 简单的比例关系。如:金币越多越富有。
Quadratic (二次) J 极端值才重要。如:只有极度靠近悬崖时,恐惧感才急剧上升。
Logistic (S形) S 阈值敏感。如:血量在 40%-60% 之间时,治疗欲望从低急剧变高。
Logit (对数) J 边际递减。如:前 100 金币很珍贵,之后的一百万金币效用递减。

2.2 组合公式 (Aggregation)

如何将多个因素组合成一个最终分数?


3. 架构设计 (Architecture Design)

在 Unity 中,我们可以使用 ScriptableObject 构建高度模块化的 Utility 系统。

3.1 核心组件

  1. Context (上下文): 包含 AI 自身、目标、世界状态的数据包。
  2. Consideration (考虑因素):
    • 输入: Context
    • 参数: AnimationCurve (响应曲线)
    • 输出: 0-1 的 float
  3. Action (行为):
    • 包含一组 Consideration
    • 最终得分 = 所有 Consideration 的乘积。
  4. Brain (大脑/决策器):
    • 每帧(或每0.1秒)遍历所有 Action
    • 执行得分最高的 Action

3.2 代码结构示例

// 1. 考虑因素基类
public abstract class Consideration : ScriptableObject {
    public AnimationCurve responseCurve;
    public abstract float Score(AIContext context);
    
    protected float Map(float rawValue) {
        return responseCurve.Evaluate(Mathf.Clamp01(rawValue));
    }
}

// 2. 具体实现:我的血量
[CreateAssetMenu(menuName = "AI/Considerations/My Health")]
public class HealthConsideration : Consideration {
    public override float Score(AIContext context) {
        // 归一化血量
        float rawHealth = context.self.currentHealth / context.self.maxHealth;
        // 如果曲线是反向的(血越少分越高),在编辑器里画一条从左上(0,1)到右下(1,0)的线
        return Map(rawHealth);
    }
}

// 3. 行为定义
[CreateAssetMenu(menuName = "AI/Action")]
public class UtilityAction : ScriptableObject {
    public string actionName;
    public List<Consideration> considerations;
    
    public float Evaluate(AIContext context) {
        float score = 1f;
        foreach (var con in considerations) {
            score *= con.Score(context);
            if (score == 0) return 0; // 剪枝优化
        }
        return score;
    }
}

4. 最佳实践与优化 (Best Practices)

4.1 惯性 (Inertia) / 滞后 (Hysteresis)

为了防止 AI 在两个分数相近的行为之间疯狂切换 (抖动),需要引入“惯性”。

4.2 双层架构 (Dual-Layer)

Utility AI 负责决策 (Decision Making),FSM/行为树负责执行 (Execution)

4.3 性能优化


5. 业界案例 (Industry Cases)

The Sims (模拟人生)

Killzone 2 (杀戮地带 2)


6. 扩展阅读