跳到主要内容

战斗 AI

MCE 使用可插拔的策略模式来实现战斗 AI。AI 系统基于 BattleAI 基类和一系列 BattleAction 组件构建,可以组合它们来创建不同的难度级别和行为风格。

架构

AI 管线分为两层:

  1. BattleAI -- 接收当前战斗状态并返回 BattleAction 的入口点。
  2. BattleAction 组件 -- 独立的决策单元,评估战斗的某一方面(例如"我应该使用效果拔群的招式吗?"或"我应该切换到抗性怪兽吗?")。

一个 BattleAI 实例持有一个有序的 BattleAction 组件列表。它按优先级顺序评估它们,第一个产生有效行动的组件获胜。

内置 AI 策略

MCE 附带多种可混合搭配的 AI 策略:

RandomBattleAI

最简单的 AI。每回合随机选择一个有效招式。

  • 难度:非常简单
  • 使用场景:野生遭遇、前期训练师
  • 行为:从可用招式中随机选择。没有策略思考。

PerformEffectiveMove

选择对当前目标造成最有效伤害的招式。

  • 难度:中等
  • 使用场景:中期训练师、道馆馆主
  • 行为:计算每个可用招式的属性克制并选择最佳招式。不考虑能力值变化或变化招式。

PerformRandomMove

类似于 RandomBattleAI 但带有加权招式选择。

  • 难度:简单
  • 使用场景:低等级训练师
  • 行为:随机选择招式,略微偏好伤害招式而非变化招式。

内置行动组件

这些组件可以组合成自定义 AI 策略:

组件描述
PerformEffectiveMove使用属性克制最佳的招式
PerformRandomMove使用随机招式
MegaOrGigaIfCan如果可以则激活 Mega 进化或极巨化
SwitchToEffectiveMonster切换到具有属性优势的队伍成员
UseBattleItemsHP 低时使用治疗或状态道具
IfWildWithRunChanceRun野生怪兽可能尝试逃跑

为每个训练师配置 AI

每个训练师 NPC 可以有不同的 AI 配置:

  1. 在训练师的 Actor 或遭遇数据上,找到 AI Configuration 字段。
  2. 分配一个 BattleAI ScriptableObject。
  3. 配置行动组件列表及其优先级顺序。

配置示例:

简单训练师(路线 1)

1. PerformRandomMove

中等训练师(道馆谜题)

1. MegaOrGigaIfCan
2. PerformEffectiveMove
3. PerformRandomMove(备选)

困难训练师(冠军)

1. MegaOrGigaIfCan
2. SwitchToEffectiveMonster(处于劣势时)
3. UseBattleItems(HP < 25% 时)
4. PerformEffectiveMove
5. PerformRandomMove(备选)

IBattleAI 接口

对于 DLL 版本用户,AI 系统通过 BattleAI 基类访问。虽然没有源代码无法修改内部实现,但你可以:

  1. 在编辑器中创建新的 BattleAI ScriptableObject。
  2. 通过 Inspector 配置行动组件列表。
  3. 将它们分配给训练师。

关键接口:

public abstract class BattleAI : ScriptableObject
{
// 按顺序评估的 BattleAction 组件列表
public List<BattleAction> Actions;
}

public abstract class BattleAction : ScriptableObject
{
// 评估是否应该执行此行动
// 如果此行动不适用则返回 null
public abstract BattleActionResult Evaluate(BattleContext context);
}

ML-Agents 集成

MCE 包含实验性的基于 ML-Agents 的 AI,用于高级难度:

MLBattleAI

使用 Unity ML-Agents 基于训练好的神经网络做出决策。

  • 难度:可变(取决于训练)
  • 使用场景:终盘训练师、竞技 AI、研究
  • 设置:需要 ML-Agents 包和训练好的模型

训练 AI

  1. 安装 ML-Agents 依赖:.\MLAgentsInstall.ps1
  2. MLAgentsConfig/OpenMonAgent.yaml 中配置训练参数
  3. 开始训练:.\RunMLTraining.ps1
  4. 使用 TensorBoard 监控:.\ViewMLResults.ps1
  5. 导出训练好的模型(.onnx 文件)
  6. 将模型分配给 MLBattleAI 组件

MCEBattleAgent 类定义了观察空间和动作空间:

观察(AI 看到的内容):

  • 自身怪兽的 HP 百分比、属性、能力值等级、状态异常。
  • 对手怪兽的 HP 百分比、属性、能力值等级、状态异常。
  • 可用招式及其属性。
  • 队伍状态(剩余怪兽、HP 百分比)。

动作(AI 可以执行的操作):

  • 使用招式 1-4。
  • 切换到队伍成员 1-5。
  • 使用道具。
ML-Agents 依赖

ML-Agents 是一个独立的包,有其自己的 Python 依赖。核心 MCE 战斗系统不需要它即可工作。只有在计划使用基于神经网络的 AI 时才安装 ML-Agents。

创建自定义 AI(Source 版本)

拥有源代码访问权限后,你可以创建全新的 AI 策略:

自定义 BattleAction

[CreateAssetMenu(menuName = "OpenMon/AI/Actions/Use Status Move If No Status")]
public class UseStatusMoveIfNoStatus : BattleAction
{
public override BattleActionResult Evaluate(BattleContext context)
{
// 检查对手是否没有状态异常
if (context.OpponentBattler.StatusCondition != StatusCondition.None)
return null; // 跳过此行动

// 寻找一个施加状态的招式
foreach (var moveSlot in context.OwnBattler.MoveSlots)
{
if (moveSlot.Move.Category == MoveCategory.Status
&& moveSlot.CurrentPP > 0
&& moveSlot.Move.InflictsStatus)
{
return new BattleActionResult
{
ActionType = BattleActionType.UseMove,
MoveIndex = moveSlot.Index
};
}
}

return null; // 没有找到适用的状态招式
}
}

自定义 BattleAI

[CreateAssetMenu(menuName = "OpenMon/AI/Strategies/Expert AI")]
public class ExpertBattleAI : BattleAI
{
// 如果需要可以覆盖决策管线
public override BattleActionResult DecideAction(BattleContext context)
{
// 超越简单行动组合的自定义逻辑
// 例如前瞻预测、队伍协同分析
return base.DecideAction(context);
}
}

AI 难度指南

难度AI 组件使用场景
非常简单仅随机招式野生遭遇
简单加权随机招式早期路线、初级训练师
中等属性克制感知道馆训练师、对手
困难克制 + 切换 + 道具道馆馆主、四天王
专家完整组合 + 预测冠军、通关后内容
神经网络ML 训练模型竞技、挑战模式

最佳实践

  1. 将 AI 与叙事场景匹配。一个随机的虫系捕手不应该像冠军一样战斗。
  2. 用相似等级的玩家队伍测试 AI。不平衡的 AI 让人感觉不公平。
  3. 使用行动组件模式。它比单体 AI 脚本更易于维护。
  4. 提供备选方案。始终将 PerformRandomMove 作为最后一个行动,以防止 AI 卡住。
  5. 不要对早期训练师过度优化 AI。玩家需要在面对聪明对手之前学习系统。