# turn-based-combat-simulator **Repository Path**: Ruemo/turn-based-combat-simulator ## Basic Information - **Project Name**: turn-based-combat-simulator - **Description**: 回合制游戏核心战斗系统 - **Primary Language**: C# - **License**: GPL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-02-21 - **Last Updated**: 2026-06-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 回合制战斗系统设计文档 ## 一、系统概述 基于 Unity UGUI + EcaTriggerSystem(事件-条件-动作触发器系统)实现的 6v6 回合制自动战斗模拟器。 - 双方各 6 个角色卡牌(UGUI Button),显示角色名称和 HP 条 - 释放技能时移动到目标旁边后快速返回 - 顶部显示本轮行动顺序队列(12 个按钮,按速度排序) - 底部重播按钮 - 终端打印完整战斗过程日志 - 动画效果使用 DOTween 实现 ![效果演示](./回合制项目演示.gif) --- ## 二、目录结构 ``` Assets/Scripts/BattleSystem/ ├── Config/ │ ├── BattleCharacterConfig.json # 角色配置(12个角色) │ ├── BattleSkillConfig.json # 技能配置(8个技能) │ └── HeroTriggerConfig.json # 英雄触发器配置(20个英雄,JSON驱动) ├── Core/ │ ├── IBattleState.cs # 状态机接口定义 │ ├── BattleStateMachine.cs # 状态机管理器 │ ├── BattleContext.cs # 战斗上下文(继承 CombatContext,含调试功能) │ ├── BattleSimulator.cs # 战斗主控 MonoBehaviour(含 TriggerManager) │ ├── TurnManager.cs # 回合排序管理(含DOT/HOT/能量结算) │ ├── DOTSystem.cs # DOT/HOT回合结算系统 │ ├── ElementalSystem.cs # 种族克制系统(水火草三系) │ └── EnergySystem.cs # 能量消耗/回复系统 ├── Data/ │ ├── BattleCharacterData.cs # 角色数据结构 + JSON序列化类 │ ├── BattleSkillData.cs # 技能数据结构 + JSON序列化类 │ ├── BattleConfigLoader.cs # JSON 配置加载器 │ ├── HeroConfigData.cs # 英雄配置数据结构(含触发器解析) │ └── HeroConfigLoader.cs # 英雄配置加载器(加载JSON → 注册触发器) ├── States/ │ ├── BattleInitState.cs # 初始化状态 │ ├── TurnStartState.cs # 回合开始状态 │ ├── ActionState.cs # 执行行动状态 │ ├── TurnEndState.cs # 回合结束状态 │ └── BattleEndState.cs # 战斗结束状态 ├── Actions/ │ ├── MoveToTargetAction.cs # 移动到目标(ECA动作) │ └── MoveBackAction.cs # 返回原位(ECA动作) ├── Conditions/ │ └── BattleConditions.cs # IsAlive / IsMyTurn / TargetFaction ├── HeroSkills/ │ └── HeroSkillBase.cs # 枚举定义(HeroRace/Career/Quality/ElementalType)+ 属性数据类 ├── UI/ │ ├── BattleUIController.cs # UI 主控制器 │ ├── CharacterCard.cs # 角色卡牌组件 │ ├── TurnQueueItem.cs # 行动队列项组件 │ └── TurnQueueUI.cs # 行动队列管理 └── BattleScene.cs # 场景入口 MonoBehaviour ``` --- ## 三、核心接口设计 ### 3.1 IBattleState(`Core/IBattleState.cs`) ```csharp public interface IBattleState { void Enter(BattleContext context); IEnumerator Execute(BattleContext context); void Exit(BattleContext context); string StateName { get; } } public interface IBattleStateMachine { void ChangeState(IBattleState newState); IBattleState GetCurrentState(); void Update(); bool IsRunning { get; } } public interface IActionExecutor { IEnumerator ExecuteAction(BattleCharacterData actor, BattleCharacterData target, BattleSkillData skill); } public interface ITurnOrderProvider { List GetTurnOrder(List characters); } ``` --- ## 四、数据结构设计 ### 4.1 BattleCharacterData(`Data/BattleCharacterData.cs`) | 字段 | 类型 | 说明 | |------|------|------| | `characterID` | `int` | 角色唯一ID | | `characterName` | `string` | 角色名称 | | `faction` | `FactionType` | 阵营(Player=0, Enemy=1) | | `position` | `int` | 站位 0-5 | | `maxHP` / `currentHP` | `int` | 生命值 | | `attack` | `int` | 攻击力 | | `defense` | `int` | 防御力 | | `speed` | `int` | 速度(决定行动顺序) | | `skillIDs` | `List` | 拥有的技能ID列表 | | `isAlive` | `bool` | 是否存活 | | `originalPosition` | `Vector3` | UI 原始位置(用于移动返回) | | `cardUI` | `CharacterCard` | 关联的 UI 组件引用 | | `skillCooldowns` | `Dictionary` | 技能冷却时间 | 关键方法: - `TakeDamage(int damage)` — 扣血,HP<=0 时标记死亡 - `Heal(int healAmount)` — 回血,不超过 maxHP - `ReduceCooldowns()` — 所有技能冷却 -1 - `IsSkillReady(string skillID)` — 检查技能是否可用 - `SetSkillCooldown(string skillID, int cooldown)` — 设置冷却 ### 4.2 BattleSkillData(`Data/BattleSkillData.cs`) | 字段 | 类型 | 说明 | |------|------|------| | `skillID` | `string` | 技能唯一ID | | `skillName` | `string` | 技能名称 | | `targetType` | `TargetType` | 目标选择类型 | | `baseDamage` | `int` | 基础伤害(负值表示治疗) | | `damageType` | `DamageType` | 伤害类型 | | `cooldown` | `int` | 冷却回合数 | 目标类型枚举 `TargetType`: - `SingleEnemy` — 单体敌人 - `AllEnemy` — 所有敌人 - `SingleAlly` — 单体友方 - `AllAlly` — 所有友方 - `Self` — 自身 ### 4.3 BattleContext(`Core/BattleContext.cs`) 继承自 `EcaTriggerSystem.CombatContext`,扩展战斗系统所需字段: | 字段 | 类型 | 说明 | |------|------|------| | `teamA` / `teamB` | `List` | 双方队伍 | | `turnOrder` | `List` | 行动顺序队列 | | `currentTurnIndex` | `int` | 当前行动索引 | | `currentRound` | `int` | 当前回合数 | | `roundLimit` | `int` | 回合上限(默认50) | | `currentActor` | `BattleCharacterData` | 当前行动角色 | | `currentTarget` | `BattleCharacterData` | 当前目标 | | `currentSkill` | `BattleSkillData` | 当前使用技能 | | `isBattleEnded` | `bool` | 战斗是否结束 | | `winner` | `FactionType?` | 胜利方 | | `skillDataMap` | `Dictionary` | 技能数据字典 | | `battleSimulator` | `BattleSimulator` | 战斗主控引用 | | `uiController` | `BattleUIController` | UI 控制器引用 | ### 4.4 UNITY_EDITOR 调试功能(`#if UNITY_EDITOR`) | 字段/方法 | 类型 | 说明 | |-----------|------|------| | `isDebugMode` | `bool` | 是否启用调试模式(默认 true) | | `isPaused` | `bool` | 是否暂停(默认 true) | | `skipCurrentTurn` | `bool` | 跳过当前回合 | | `debugStepCount` | `int` | 调试步数计数 | | `DebugStep()` | 方法 | 取消暂停,步数+1 | | `DebugSkipTurn()` | 方法 | 设置跳过当前回合并取消暂停 | | `SetDebugMode(bool)` | 方法 | 设置调试模式,关闭时自动取消暂停 | 关键方法: - `GetAllCharacters()` / `GetAliveCharacters()` — 获取全部/存活角色 - `GetAliveEnemies(FactionType)` / `GetAliveAllies(FactionType)` — 按阵营获取 - `GetCurrentTurnCharacter()` — 获取当前行动角色(跳过死亡) - `CheckBattleEnd()` — 检查胜负条件 - `InitializeTurnOrder()` — 按速度降序初始化行动队列 - `GetTurnOrderString()` — 获取行动顺序字符串 --- ## 五、状态机设计 ### 5.1 BattleStateMachine(`Core/BattleStateMachine.cs`) - 持有 `BattleContext` 引用 - `StartMachine(IBattleState)` — 启动协程驱动状态机 - `ChangeState(IBattleState)` — 切换状态(执行 Exit → Enter) - `RunStateMachine()` — 协程循环执行 `currentState.Execute()` ### 5.2 状态流转图 ```mermaid stateDiagram-v2 [*] --> BattleInitState state BattleInitState { [*] --> InitQueue : 按speed降序排序 InitQueue --> CreateUI : 创建角色卡牌UI CreateUI --> CreateTurnQueue : 创建行动队列UI CreateTurnQueue --> PrintOrder : 打印行动顺序 } BattleInitState --> TurnStartState state TurnStartState { [*] --> GetActor : 获取当前行动角色 GetActor --> Highlight : 高亮角色 DOScale 1.1x Highlight --> QueueHighlight : 队列项 DOScale 1.2x OutBack } TurnStartState --> ActionState state ActionState { [*] --> SelectSkill : 随机选择可用技能 SelectSkill --> SelectTargets : 根据TargetType选目标 SelectTargets --> PublishSkill : 发布SKILL_CAST事件 PublishSkill --> MoveToTarget : DOLocalMove Ease.OutQuad MoveToTarget --> CalcDamage : 计算伤害并应用 CalcDamage --> PublishDamage : 发布RECEIVE_DAMAGE事件 PublishDamage --> MoveBack : DOLocalMove Ease.InQuad MoveBack --> Log : 终端输出日志 } ActionState --> TurnEndState state TurnEndState { [*] --> UpdateHP : 更新HP显示 DOValue UpdateHP --> UpdateDead : 更新死亡显示 DOFade+DOColor UpdateDead --> CheckEnd : 检查战斗结束 CheckEnd --> RoundSwitch : 回合切换 RoundSwitch --> RefreshQueue : 刷新队列+减少冷却 } TurnEndState --> BattleEndState : 战斗结束 TurnEndState --> TurnStartState : 继续战斗 state BattleEndState { [*] --> PublishEnd : 发布BATTLE_END事件 PublishEnd --> PrintResult : 打印战斗结果 PrintResult --> ShowPanel : 显示结果面板 ShowPanel --> EnableReplay : 启用重播按钮 } BattleEndState --> [*] ``` ### 5.3 各状态职责 | 状态 | 文件 | 职责 | |------|------|------| | `BattleInitState` | `States/BattleInitState.cs` | 初始化队列、创建 UI、打印行动顺序 | | `TurnStartState` | `States/TurnStartState.cs` | 获取当前角色、高亮显示、跳过死亡角色 | | `ActionState` | `States/ActionState.cs` | 技能选择、目标选择、移动动画、伤害计算、事件发布 | | `TurnEndState` | `States/TurnEndState.cs` | 更新 UI、检查胜负、回合切换 | | `BattleEndState` | `States/BattleEndState.cs` | 发布结束事件、显示结果、启用重播 | --- ## 六、战斗流程 ### 6.1 启动流程 ``` BattleScene.Start() → BattleSimulator.Awake() # 初始化 Context、StateMachine、TurnManager → BattleSimulator.StartBattle() # 加载配置 → 分队 → 初始化UI → 启动状态机 ``` ### 6.2 回合流程 ``` 1. ActionState.SelectSkill() # 从可用技能中随机选择 2. ActionState.SelectTargets() # 根据 TargetType 选择目标 - SingleEnemy: 随机一个敌方存活角色 - AllEnemy: 所有敌方存活角色 - SingleAlly: 优先选择受伤友方,否则随机 - AllAlly: 所有友方存活角色 - Self: 自身 3. CombatEventBus.Publish(SKILL_CAST) 4. CharacterCard.MoveToTarget() # DOTween DOLocalMove, Ease.OutQuad 5. BattleSimulator.CalculateDamage() - finalDamage = baseDamage * (attack / 100) - damageType != True: finalDamage *= (1 - defense / (defense + 100)) - 种族克制: finalDamage *= ElementalSystem.GetDamageMultiplier() (克制1.3x/被克0.77x) - 最低 1 点伤害 6. BattleSimulator.ApplyDamage() # 扣血/治疗 + 更新 UI 7. CombatEventBus.Publish(RECEIVE_DAMAGE) 8. CharacterCard.MoveBack() # DOTween DOLocalMove, Ease.InQuad 9. → TurnEndState → 检查胜负 → TurnStartState(循环) ``` ### 6.3 回合切换 - 所有角色行动完一轮后 `currentTurnIndex` 归零,`currentRound++` - **DOT/HOT结算**:`DOTSystem.ProcessAllDOTs()` 结算所有中毒/燃烧/流血伤害和持续恢复,按 `remainingRounds` 倒计 - **非DOT buff/debuff回合倒计**:`TickOtherBuffs/TickOtherDebuffs()` 统一按回合倒计 - 所有角色技能冷却 -1 - **能量回复**:`EnergySystem.ProcessEnergyRegen()` 每回合按 `energyRegen` 回复能量 - 重新按速度排序刷新行动队列 ### 6.4 胜负判定 - 玩家方全灭 → 敌方胜利 - 敌方全灭 → 玩家胜利 - 达到回合上限(50) → 平局 --- ## 七、伤害计算公式 ``` finalDamage = baseDamage × (attacker.attack / 100) if damageType != True: damageReduction = defender.defense / (defender.defense + 100) finalDamage ×= (1 - damageReduction) // 种族克制(水火草三系) elementalMultiplier = ElementalSystem.GetDamageMultiplier(attackerRace, defenderRace) if elementalMultiplier != 1.0: finalDamage ×= elementalMultiplier // 克制 1.3x / 被克 0.77x / 中立 1.0x finalDamage = max(1, round(finalDamage)) ``` - `baseDamage < 0` 表示治疗技能,直接返回原始值 - `DamageType.True`(真实伤害)无视防御 - **种族克制**(`ElementalSystem`): - 水(Castle) → 火(Hell/Necropolis) → 草(Sylva/Dungeon) → 水 - Heaven 为中立系,不参与克制 - 克制倍率:1.3x / 被克倍率:0.77x --- ## 7.5 英雄枚举与属性定义(`HeroSkills/HeroSkillBase.cs`) ### HeroRace(种族) | 枚举值 | 说明 | 元素属性 | |--------|------|---------| | `Castle` | 城堡 | 水(Water) | | `Necropolis` | 亡灵 | 火(Fire) | | `Hell` | 地狱 | 火(Fire) | | `Sylva` | 森林 | 草(Grass) | | `Dungeon` | 地下城 | 草(Grass) | | `Heaven` | 天堂 | 中立(Neutral) | ### HeroCareer(职业) | 枚举值 | 说明 | |--------|------| | `Warrior` | 战士 | | `Mage` | 法师 | | `Ranger` | 游侠 | | `Assassin` | 刺客 | | `Priest` | 牧师 | ### HeroQuality(品质) | 枚举值 | 说明 | |--------|------| | `N` | 普通 | | `A` | 精良 | | `S` | 史诗 | | `SS` | 传说 | ### ElementalType(元素属性) | 枚举值 | 说明 | |--------|------| | `Water` | 水 | | `Fire` | 火 | | `Grass` | 草 | | `Neutral` | 中立 | ### HeroAttributeData(英雄属性数据类) | 字段 | 类型 | 说明 | |------|------|------| | `hp` | `int` | 生命值 | | `atk` | `int` | 攻击力 | | `def` | `int` | 防御力 | | `spd` | `int` | 速度 | | `crt` | `int` | 暴击率 | | `crtDmg` | `int` | 暴击伤害 | | `accurate` | `int` | 精准度 | | `block` | `int` | 格挡率 | --- ## 八、UI 设计 ### 8.1 布局结构 ``` Canvas ├── TurnQueuePanel (HorizontalLayoutGroup, 顶部) │ ├── TurnQueueItem[0] (Button + Text: 角色名) │ ├── TurnQueueItem[1] │ ├── ... │ └── TurnQueueItem[11] │ ├── BattleArea (中部) │ ├── EnemyTeam (GridLayoutGroup 2×3, 上方) │ │ ├── CharacterCard[0] (Button) │ │ │ ├── NameText │ │ │ └── HPBar (Slider) │ │ └── ... (共6个) │ │ │ └── PlayerTeam (GridLayoutGroup 2×3, 下方) │ ├── CharacterCard[0] │ └── ... (共6个) │ └── BottomPanel ├── StartButton (开始战斗) ├── ReplayButton (重播, 战斗结束后显示) └── ResultPanel (战斗结果文字) ``` ### 8.2 CharacterCard 组件(`UI/CharacterCard.cs`) | 序列化字段 | 类型 | 说明 | |-----------|------|------| | `nameText` | `Text` | 角色名称 | | `hpBar` | `Slider` | HP 条 | | `background` | `Image` | 背景色(区分阵营) | | `button` | `Button` | 按钮组件 | | `canvasGroup` | `CanvasGroup` | 透明度控制 | 颜色方案: - 玩家方:`RGB(0.3, 0.6, 1.0)` 蓝色 - 敌方:`RGB(1.0, 0.3, 0.3)` 红色 - 死亡:`RGB(0.5, 0.5, 0.5, 0.5)` 灰色半透明 - 高亮:`RGB(1.0, 1.0, 0.5)` 黄色 DOTween 动画: - `SetHighlight(true)` → DOScale(1.1f) + DOColor(highlightColor), Ease.OutQuad, 0.2s - `MoveToTarget()` → DOLocalMove, Ease.OutQuad - `MoveBack()` → DOLocalMove, Ease.InQuad - `UpdateHPDisplay()` → hpBar.DOValue, 0.3s - `SetDeadAppearance()` → DOColor(deadColor) + DOFade(0.5f), 0.3s ### 8.3 TurnQueueItem 组件(`UI/TurnQueueItem.cs`) DOTween 动画: - `SetCurrentTurn(true)` → DOScale(1.2f), Ease.OutBack(弹性效果) - `SetDead()` → DOScale(0.8f) + DOColor(deadColor) + DOFade(0.4f) - `PlayRemoveAnimation()` → DOScale(0), Ease.InBack, 0.3s 后销毁 ### 8.4 BattleUIController(`UI/BattleUIController.cs`) - `Initialize()` — 绑定按钮事件、隐藏结果面板和重播按钮 - `CreateCharacterCards()` — 动态实例化双方角色卡牌,自动查找子组件 - `CreateTurnQueue()` — 动态实例化行动队列项 - `HighlightCurrentActor()` — 高亮当前角色 + 队列项 - `UpdateTurnQueueDisplay()` — 更新 HP 显示 + 死亡状态 - `ShowBattleEnd()` — 显示胜利/失败/平局结果 - `ClearUI()` — 重播时清除所有 UI ### 8.5 TurnQueueUI(`UI/TurnQueueUI.cs`) - `CreateQueue()` — 根据行动顺序创建队列项(仅存活角色) - `UpdateCurrentTurn()` — 高亮当前行动角色 - `UpdateDeadCharacters()` — 标记死亡角色 - `RefreshQueue()` — 新回合刷新队列 --- ## 九、配置文件 ### 9.1 BattleCharacterConfig.json ```json { "characters": [ { "id": 1001, "name": "剑士", "faction": 0, "position": 0, "hp": 800, "attack": 120, "defense": 30, "speed": 100, "skills": ["normal_attack", "skill_slash"] } ] } ``` 预设 12 个角色(6v6): | ID | 名称 | 阵营 | HP | 攻击 | 防御 | 速度 | 技能 | |----|------|------|-----|------|------|------|------| | 1001 | 剑士 | 玩家 | 800 | 120 | 30 | 100 | 普攻, 斩击 | | 1002 | 法师 | 玩家 | 500 | 150 | 15 | 90 | 普攻, 火球术 | | 1003 | 牧师 | 玩家 | 600 | 80 | 20 | 85 | 普攻, 治疗术 | | 1004 | 弓手 | 玩家 | 550 | 130 | 18 | 110 | 普攻, 穿云箭 | | 1005 | 骑士 | 玩家 | 1000 | 90 | 50 | 70 | 普攻, 盾击 | | 1006 | 刺客 | 玩家 | 450 | 160 | 10 | 130 | 普攻, 背刺 | | 2001 | 哥布林A | 敌方 | 300 | 50 | 10 | 80 | 普攻 | | 2002 | 哥布林B | 敌方 | 300 | 50 | 10 | 75 | 普攻 | | 2003 | 兽人 | 敌方 | 600 | 80 | 25 | 60 | 普攻, 斩击 | | 2004 | 骷髅兵 | 敌方 | 250 | 60 | 5 | 95 | 普攻 | | 2005 | 暗法师 | 敌方 | 400 | 120 | 12 | 88 | 普攻, 火球术 | | 2006 | 巨魔 | 敌方 | 800 | 100 | 35 | 55 | 普攻, 猛击 | ### 9.2 BattleSkillConfig.json ```json { "skills": [ { "skillID": "normal_attack", "skillName": "普通攻击", "targetType": "SingleEnemy", "baseDamage": 100, "damageType": "Physical", "cooldown": 0 } ] } ``` 预设 8 个技能: | 技能ID | 名称 | 目标类型 | 基础伤害 | 伤害类型 | 冷却 | |--------|------|---------|---------|---------|------| | normal_attack | 普通攻击 | SingleEnemy | 100 | Physical | 0 | | skill_slash | 斩击 | SingleEnemy | 150 | Physical | 2 | | skill_fireball | 火球术 | AllEnemy | 80 | Magical | 3 | | skill_heal | 治疗术 | SingleAlly | -100 | Magical | 2 | | skill_arrow | 穿云箭 | SingleEnemy | 180 | Physical | 2 | | skill_shield | 盾击 | SingleEnemy | 80 | Physical | 1 | | skill_backstab | 背刺 | SingleEnemy | 250 | Physical | 3 | | skill_slam | 猛击 | SingleEnemy | 200 | Physical | 2 | ### 9.3 HeroTriggerConfig.json 英雄技能已从独立代码类重构为 **JSON 配置驱动** 模式,通过 `HeroConfigLoader` 加载并注册到 `TriggerManager`。 ```json { "heroes": [ { "heroID": 1, "heroName": "圣盾骑士", "race": "Castle", "career": "Warrior", "quality": "SS", "attributes": {"hp": 15000, "atk": 800, "def": 1200, "spd": 80}, "triggers": [ { "triggerID": "holy_shield_knight_shield", "triggerName": "神圣护盾", "ownerID": 1, "conditionType": "EventType", "conditionParams": {"eventType": "BATTLE_START"}, "actionType": "Compound", "actionParams": { "actions": [...] } } ] } ] } ``` 英雄属性结构(`attributes`): | 字段 | 类型 | 说明 | |------|------|------| | `hp` | `int` | 生命值 | | `atk` | `int` | 攻击力 | | `def` | `int` | 防御力 | | `spd` | `int` | 速度 | | `crt` | `int` | 暴击率(可选) | | `crtDmg` | `int` | 暴击伤害(可选) | | `accurate` | `int` | 精准度(可选) | | `block` | `int` | 格挡率(可选) | 预设 20 个英雄: | ID | 名称 | 种族 | 职业 | 品质 | HP | 攻击 | 防御 | 速度 | 核心触发器 | |----|------|------|------|------|-----|------|------|------|-----------| | 1 | 圣盾骑士 | Castle | Warrior | SS | 15000 | 800 | 1200 | 80 | 神圣护盾、坚守阵地 | | 2 | 暗影刺客 | Necropolis | Assassin | SS | 8000 | 1500 | 400 | 150 | 致命突袭、暗影标记、暴击精通 | | 3 | 自然德鲁伊 | Sylva | Priest | SS | 10000 | 600 | 600 | 100 | 生命绽放、自然之愈 | | 4 | 火焰法师 | Dungeon | Mage | SS | 7000 | 1800 | 300 | 110 | 烈焰风暴、灼烧印记 | | 5 | 天使守卫 | Heaven | Priest | SS | 12000 | 700 | 800 | 90 | 神圣复活(50%)、天使庇护 | | 6 | 恶魔猎手 | Hell | Ranger | SS | 9000 | 1400 | 500 | 130 | 灵魂汲取、恶魔之血 | | 7 | 冰霜女巫 | Dungeon | Mage | S | 7500 | 1600 | 350 | 105 | 冰封术、寒冰护甲 | | 8 | 荆棘战士 | Sylva | Warrior | S | 14000 | 900 | 1000 | 85 | 荆棘之甲、荆棘反伤、反击姿态 | | 9 | 剧毒猎手 | Necropolis | Ranger | S | 8500 | 1300 | 450 | 140 | 毒箭、剧毒爆发 | | 10 | 圣光牧师 | Castle | Priest | S | 9500 | 650 | 550 | 95 | 净化之光、神圣祝福 | | 11 | 狂战士 | Hell | Warrior | S | 13000 | 1200 | 600 | 100 | 狂暴、不死之身(30%) | | 12 | 暗影术士 | Necropolis | Mage | S | 7200 | 1700 | 320 | 108 | 生命链接、灵魂收割 | | 13 | 精灵射手 | Sylva | Ranger | A | 8000 | 1100 | 400 | 135 | 精准射击、弱点洞察 | | 14 | 盾卫 | Castle | Warrior | A | 16000 | 700 | 1100 | 70 | 坚守、嘲讽 | | 15 | 闪电法师 | Heaven | Mage | A | 6800 | 1400 | 300 | 115 | 连锁闪电、静电护盾 | | 16 | 血族伯爵 | Necropolis | Assassin | SS | 9500 | 1450 | 450 | 145 | 鲜血盛宴(30%吸血)、血之狂怒 | | 17 | 石像鬼 | Dungeon | Warrior | A | 18000 | 600 | 1300 | 60 | 石化皮肤、石化凝视 | | 18 | 风行者 | Sylva | Assassin | A | 7500 | 1200 | 350 | 160 | 疾风步、风刃(闪避反击) | | 19 | 光明骑士 | Heaven | Warrior | SS | 14500 | 1000 | 900 | 95 | 神圣打击、圣光庇护 | | 20 | 堕落天使 | Hell | Mage | SS | 7800 | 1750 | 380 | 120 | 黑暗契约(能量)、堕落审判 | --- ## 十、与 EcaTriggerSystem 集成 ### 10.1 架构模式:JSON 配置驱动 英雄技能系统采用 **JSON 配置驱动** 模式,不再使用独立的英雄代码类。配置加载流程: ``` HeroTriggerConfig.json → HeroConfigLoader.LoadHeroes() # 解析 JSON → HeroConfigData → HeroConfigData.FromConfig() # 每个英雄的 triggers → TriggerConfigLoader.LoadTriggerFromConfig() → TriggerManager.RegisterTrigger() # 注册到触发器管理器 → SetupCharacterDataFromConfig() # 设置角色的 race/career/quality/customData → CombatEventBus.Publish(BATTLE_START) # 发布开始事件激活被动触发器 ``` ### 10.2 继承关系 ``` EcaTriggerSystem.CombatContext └── BattleSystem.BattleContext (扩展队伍、回合、技能等字段) ``` ### 10.3 新增数据类(`Data/HeroConfigData.cs`) | 类 | 说明 | |----|------| | `HeroAttributeConfig` | 英雄属性配置(hp/atk/def/spd/crt/crtDmg/accurate/block) | | `HeroTriggerConfig` | 单个触发器配置(triggerID/conditionType/actionType/params/ownerID) | | `HeroConfig` | 英雄完整配置(heroID/heroName/race/career/quality/attributes/triggers) | | `HeroConfigList` | 英雄配置列表容器 | | `HeroConfigData` | 运行时英雄数据(含 parsedTriggers + triggerManager) | `HeroConfigData.FromConfig()` 关键流程:遍历 triggers → 构建 `TriggerConfig` → 调用 `TriggerConfigLoader.LoadTriggerFromConfig()` 解析为 `CombatTrigger`。 ### 10.4 新增加载器(`Data/HeroConfigLoader.cs`) | 方法 | 说明 | |------|------| | `LoadHeroes(configPath, context, triggerManager)` | 加载 JSON → 创建 HeroConfigData → 注册触发器 → 返回字典 | | `SetupCharacterDataFromConfig(heroDataMap, context, characterID)` | 将英雄的 race/career/quality 写入角色 customData;自动判断阵营(Necropolis/Hell/Dungeon → Enemy) | ### 10.5 事件发布 | 事件 | 触发时机 | 发布位置 | |------|---------|---------| | `BATTLE_START` | 战斗开始时(每个角色) | `BattleSimulator.SetupHeroTriggers()` | | `SKILL_CAST` | 角色释放技能时 | `ActionState.Execute()` | | `BEFORE_ATTACK` | 攻击前 | 英雄触发器条件检测 | | `ATTACK_HIT` | 攻击命中后 | 英雄触发器条件检测 | | `RECEIVE_DAMAGE` | 受到伤害后 | `ActionState.ExecuteActionWithAnimation()` | | `DOT_TRIGGER` | DOT每回合结算时 | `DOTSystem.ProcessDOT()` | | `AFTER_GET_HEAL` | 治疗完成后 | 英雄触发器(如自然德鲁伊) | | `ALLY_DIED` | 友方死亡时 | 英雄触发器(天使守卫、光明骑士) | | `DIE` | 角色死亡时 | 英雄触发器(暗影术士灵魂收割) | | `ENEMY_DIED` | 敌方死亡时 | 英雄触发器(暗影术士灵魂收割) | | `ENERGY_CHANGE` | 能量变化时 | `EnergySystem` | | `AFTER_ROUND` | 每回合结束时 | 英雄触发器(石像鬼石化凝视) | | `DODGE` | 闪避时 | 英雄触发器(风行者风刃反击) | | `BATTLE_END` | 战斗结束时 | `BattleEndState.Execute()` | ### 10.6 扩展动作(`Actions/`) | 动作 | 说明 | |------|------| | `MoveToTargetAction` | 通过 `BattleContext` 获取 actor/target 的 `cardUI`,启动 DOTween 移动协程 | | `MoveBackAction` | 通过 `BattleContext` 获取 actor 的 `cardUI`,启动 DOTween 返回协程 | ### 10.7 扩展条件(`Conditions/BattleConditions.cs`) | 条件 | 说明 | |------|------| | `IsAliveCondition` | 检查事件目标角色是否存活 | | `IsMyTurnCondition` | 检查事件来源是否为当前行动角色 | | `TargetFactionCondition` | 检查事件目标是否属于指定阵营 | --- ## 十一、DOTween 动画效果汇总 | 动画 | API | 缓动 | 时长 | 位置 | |------|-----|------|------|------| | 角色高亮缩放 | `DOScale(1.1f)` | OutQuad | 0.2s | CharacterCard | | 移动到目标 | `DOLocalMove` | OutQuad | 0.3s | CharacterCard | | 返回原位 | `DOLocalMove` | InQuad | 0.3s | CharacterCard | | HP 条变化 | `DOValue` | - | 0.3s | CharacterCard | | 死亡变灰 | `DOColor + DOFade` | - | 0.3s | CharacterCard | | 队列当前缩放 | `DOScale(1.2f)` | OutBack | 0.2s | TurnQueueItem | | 队列死亡 | `DOScale(0.8f) + DOFade` | OutQuad | 0.2s | TurnQueueItem | | 队列移除 | `DOScale(0)` | InBack | 0.3s | TurnQueueItem | --- ## 十二、终端日志输出格式 ``` ═══════════════════════════════════════ [战斗系统] 开始加载战斗 ═══════════════════════════════════════ [战斗系统] 配置加载完成: 8 技能, 12 角色 [战斗系统] 队伍设置完成: 玩家方 6 人, 敌方 6 人 ═══════════════════════════════════════ [回合 1] 行动顺序: 刺客 > 弓手 > 剑士 > 法师 > 骷髅兵 > 暗法师 > 牧师 > 哥布林A > 哥布林B > 兽人 > 骑士 > 巨魔 ═══════════════════════════════════════ [状态:回合开始] 刺客 准备行动 [刺客] 使用 [背刺] → [哥布林A] [伤害] 哥布林A 受到 400 点伤害, 当前HP: 0/300 [死亡] 哥布林A 被击败! ... ═══════════════════════════════════════ [回合 2] 行动顺序: 刺客 > 弓手 > ... ═══════════════════════════════════════ ... ═══════════════════════════════════════ [战斗结束] 胜利方: 玩家阵营 [战斗统计] 总回合数: 5 ═══════════════════════════════════════ ``` --- ## 十三、BattleSimulator 公开方法 ### 13.1 序列化字段 | 字段 | 类型 | 说明 | |------|------|------| | `characterConfigPath` | `string` | 角色配置路径(默认 Scripts/BattleSystem/Config/BattleCharacterConfig.json) | | `skillConfigPath` | `string` | 技能配置路径(默认 Scripts/BattleSystem/Config/BattleSkillConfig.json) | | `heroConfigPath` | `string` | 英雄触发器配置路径(默认 Scripts/BattleSystem/Config/HeroTriggerConfig.json) | | `uiController` | `BattleUIController` | UI 控制器引用 | | `roundLimit` | `int` | 回合上限(默认50) | | `actionDelay` | `float` | 行动延迟 | | `moveDuration` | `float` | 移动动画时长(默认0.3s) | ### 13.2 公开属性 | 属性 | 类型 | 说明 | |------|------|------| | `Context` | `BattleContext` | 战斗上下文 | | `TurnManager` | `TurnManager` | 回合管理器 | | `StateMachine` | `BattleStateMachine` | 状态机 | | `TriggerManager` | `TriggerManager` | ECA触发器管理器 | ### 13.3 公开方法 | 方法 | 说明 | |------|------| | `StartBattle()` | 加载配置、分队、初始化英雄触发器、初始化 UI、启动状态机 | | `ReplayBattle()` | 清除 TriggerManager 和 EventBus、重置所有状态、重新开始战斗 | | `ChangeState(IBattleState)` | 状态机切换状态 | | `ExecuteMoveToTarget(actor, target)` | 执行移动到目标动画 | | `ExecuteMoveBack(actor)` | 执行返回原位动画 | | `CalculateDamage(attacker, defender, skill)` | 伤害计算(含种族克制) | | `ApplyDamage(target, damage)` | 应用伤害/治疗 + 更新 UI | | `LogBattleInfo(message)` | 输出战斗日志 | ### 13.4 内部方法 | 方法 | 说明 | |------|------| | `LoadConfigs()` | 加载技能和角色 JSON 配置,同步到 CombatContext | | `SetupTeams()` | 按 faction 分队到 teamA/teamB | | `SetupHeroTriggers()` | 加载英雄配置 → 注册触发器 → 设置角色数据 → 发布 BATTLE_START | | `GetElementalMultiplier(attackerID, defenderID)` | 通过 CombatContext 获取种族并计算克制倍率 | --- ## 十四、使用方式 ### 14.1 场景搭建 1. 创建 Canvas,添加以下层级结构: - `TurnQueuePanel`(HorizontalLayoutGroup) - `EnemyTeam`(GridLayoutGroup 2×3) - `PlayerTeam`(GridLayoutGroup 2×3) - `BottomPanel`(ReplayButton、ResultPanel) 2. 创建角色卡牌预制体(Button + Text + Slider + Image + CanvasGroup) 3. 创建队列项预制体(Button + Text + Image + Image(Border) + CanvasGroup) 4. 挂载 `BattleSimulator` 和 `BattleUIController` 到场景物体 5. 挂载 `BattleScene` 到场景入口物体 6. 在 Inspector 中拖拽引用预制体、容器、按钮等 ### 14.2 配置修改 - 编辑 `Assets/Scripts/BattleSystem/Config/BattleCharacterConfig.json` 修改角色 - 编辑 `Assets/Scripts/BattleSystem/Config/BattleSkillConfig.json` 修改技能 - 在 `BattleSimulator` Inspector 中可调整 `roundLimit`、`moveDuration` 等参数 --- ## 十五、文件清单(29个文件) | # | 文件路径 | 说明 | |---|---------|------| | 1 | `Core/IBattleState.cs` | 状态机接口 | | 2 | `Core/BattleStateMachine.cs` | 状态机管理器 | | 3 | `Core/BattleContext.cs` | 战斗上下文(含UNITY_EDITOR调试功能) | | 4 | `Core/BattleSimulator.cs` | 战斗主控(含种族克制伤害计算、TriggerManager) | | 5 | `Core/TurnManager.cs` | 回合管理(含DOT/HOT/能量结算) | | 6 | `Core/DOTSystem.cs` | DOT(Poison/Burn/Bleed) + HOT(Regeneration) 回合结算 | | 7 | `Core/ElementalSystem.cs` | 种族克制系统(水火草三系映射) | | 8 | `Core/EnergySystem.cs` | 能量消耗/回复/检查机制 | | 9 | `Data/BattleCharacterData.cs` | 角色数据 | | 10 | `Data/BattleSkillData.cs` | 技能数据 | | 11 | `Data/BattleConfigLoader.cs` | 配置加载器 | | 12 | `Data/HeroConfigData.cs` | 英雄配置数据结构(含触发器解析) | | 13 | `Data/HeroConfigLoader.cs` | 英雄配置加载器(JSON → 注册触发器) | | 14 | `States/BattleInitState.cs` | 初始化状态 | | 15 | `States/TurnStartState.cs` | 回合开始状态 | | 16 | `States/ActionState.cs` | 执行行动状态 | | 17 | `States/TurnEndState.cs` | 回合结束状态 | | 18 | `States/BattleEndState.cs` | 战斗结束状态 | | 19 | `Actions/MoveToTargetAction.cs` | 移动动作 | | 20 | `Actions/MoveBackAction.cs` | 返回动作 | | 21 | `Conditions/BattleConditions.cs` | 战斗条件 | | 22 | `HeroSkills/HeroSkillBase.cs` | 枚举定义(HeroRace/Career/Quality/ElementalType)+ HeroAttributeData | | 23 | `UI/BattleUIController.cs` | UI 主控 | | 24 | `UI/CharacterCard.cs` | 角色卡牌 | | 25 | `UI/TurnQueueItem.cs` | 队列项 | | 26 | `UI/TurnQueueUI.cs` | 队列管理 | | 27 | `BattleScene.cs` | 场景入口 | | 28 | `Config/BattleCharacterConfig.json` | 角色配置(12个角色) | | 29 | `Config/BattleSkillConfig.json` | 技能配置(8个技能) | | 30 | `Config/HeroTriggerConfig.json` | 英雄触发器配置(20个英雄) |