chore: initial commit
This commit is contained in:
674
Docs/Design/19_BossPatternLibrary.md
Normal file
674
Docs/Design/19_BossPatternLibrary.md
Normal file
@@ -0,0 +1,674 @@
|
||||
# 19 · Boss 攻击模式库(Boss Pattern Library)
|
||||
|
||||
> **命名空间** `BaseGames.Enemies.Boss.Patterns`
|
||||
> **所属文档集** [← 返回索引](./README.md) · [总览](./00_Overview.md)
|
||||
> **依赖** `BaseGames.Enemies` · `BaseGames.Combat` · `BaseGames.Feedback` · `BaseGames.Core.Events` · BehaviorDesigner · Animancer
|
||||
|
||||
---
|
||||
|
||||
## 目录
|
||||
|
||||
1. [系统总览](#1-系统总览)
|
||||
2. [攻击模式数据层](#2-攻击模式数据层)
|
||||
3. [BossOrchestrator — 运行时编排器](#3-bossorchestrator--运行时编排器)
|
||||
4. [TelegraphSystem — 预警系统](#4-telegraphsystem--预警系统)
|
||||
5. [阶段转换规则](#5-阶段转换规则)
|
||||
6. [内置攻击模式类型](#6-内置攻击模式类型)
|
||||
7. [Boss 原型模板](#7-boss-原型模板)
|
||||
8. [BehaviorDesigner 集成](#8-behaviordesigner-集成)
|
||||
9. [事件频道](#9-事件频道)
|
||||
10. [编辑器工具](#10-编辑器工具)
|
||||
|
||||
---
|
||||
|
||||
## 1. 系统总览
|
||||
|
||||
Boss 攻击模式系统将 Boss 战的**决策**与**执行**分离:
|
||||
|
||||
```
|
||||
Boss 模式系统职责:
|
||||
├─ AttackPatternSO → 单个攻击的完整数据(前摇/活跃/后摇/伤害/移动/预警)
|
||||
├─ BossPhaseConfigSO → 一个阶段的模式集合(权重、冷却、组合规则)
|
||||
├─ BossOrchestrator → 运行时编排:选模式 → 执行 → 监听结果
|
||||
├─ TelegraphSystem → 攻击前的视觉/音效预警(Surface Marker、闪光、UI 箭头)
|
||||
└─ PhaseTransitionRule → HP 阈值 → 触发阶段切换
|
||||
```
|
||||
|
||||
**设计原则**:
|
||||
- `AttackPatternSO` 完全数据化,美术/策划可在 Inspector 中配置
|
||||
- BehaviorDesigner 调用 `BossOrchestrator` 的 **Action Task**,不直接操作动画
|
||||
- 阶段切换通过 SO 事件频道广播,不在 BossBase 内硬编码
|
||||
|
||||
---
|
||||
|
||||
## 2. 攻击模式数据层
|
||||
|
||||
### AttackPatternSO — 单个攻击模式
|
||||
|
||||
```csharp
|
||||
[CreateAssetMenu(menuName = "Enemies/Boss/AttackPattern")]
|
||||
public class AttackPatternSO : ScriptableObject
|
||||
{
|
||||
[Header("基础信息")]
|
||||
public string patternId; // 唯一 ID,用于动画事件映射
|
||||
public string displayName; // 编辑器显示名
|
||||
|
||||
[Header("时序(秒)")]
|
||||
public float telegraphDuration; // 预警时长(玩家反应窗口)
|
||||
public float windupDuration; // 前摇(动画加速,不可取消)
|
||||
public float activeDuration; // 活跃帧(HitBox 开启)
|
||||
public float recoveryDuration; // 后摇(可被打断的脆弱期)
|
||||
|
||||
[Header("伤害")]
|
||||
public DamageSourceSO damageSource; // 复用战斗系统的伤害描述 SO
|
||||
public bool isParryable; // 是否可弹反
|
||||
public KnockbackProfile knockback;
|
||||
|
||||
[Header("运动控制")]
|
||||
public bool lockBossMovement; // 前摇/活跃期间锁定 Boss 移动
|
||||
public AnimationCurve movementCurve; // Boss 位移曲线(空 = 不移动)
|
||||
public float movementDistance; // 冲刺/位移距离
|
||||
|
||||
[Header("投射物")]
|
||||
public ProjectileConfigSO[] projectiles; // 发射的弹射物(可多个)
|
||||
public Vector2[] projectileDirections; // 对应发射方向
|
||||
|
||||
[Header("预警配置")]
|
||||
public TelegraphConfig telegraph; // 预警类型及参数(见 §4)
|
||||
|
||||
[Header("权重与冷却")]
|
||||
[Range(1, 10)]
|
||||
public int weight; // 选择权重(越高越常被选中)
|
||||
public float cooldown; // 同一模式的最小复用间隔(秒)
|
||||
|
||||
[Header("条件")]
|
||||
public PatternCondition[] activationConditions; // 激活条件(距离/玩家位置/HP范围)
|
||||
}
|
||||
```
|
||||
|
||||
### PatternCondition — 激活条件
|
||||
|
||||
```csharp
|
||||
[Serializable]
|
||||
public struct PatternCondition
|
||||
{
|
||||
public ConditionType type;
|
||||
|
||||
// ── InRange ──
|
||||
public float minRange;
|
||||
public float maxRange;
|
||||
|
||||
// ── HPBelow / HPAbove ──
|
||||
[Range(0f, 1f)] public float hpThreshold;
|
||||
|
||||
// ── PlayerIsAbove / PlayerIsBelow / PlayerIsBehind ──
|
||||
// 无额外参数
|
||||
}
|
||||
|
||||
public enum ConditionType
|
||||
{
|
||||
InRange, // 玩家在 [minRange, maxRange] 内
|
||||
OutOfRange, // 玩家在 maxRange 外
|
||||
HPBelow, // Boss HP < hpThreshold
|
||||
HPAbove, // Boss HP > hpThreshold
|
||||
PlayerIsAbove, // 玩家高于 Boss(触发对空攻击)
|
||||
PlayerIsBelow, // 玩家低于 Boss(触发下方攻击)
|
||||
PlayerIsBehind, // 玩家在 Boss 身后(触发转身攻击)
|
||||
Always, // 无条件(默认)
|
||||
}
|
||||
```
|
||||
|
||||
### BossPhaseConfigSO — 阶段配置
|
||||
|
||||
```csharp
|
||||
[CreateAssetMenu(menuName = "Enemies/Boss/PhaseConfig")]
|
||||
public class BossPhaseConfigSO : ScriptableObject
|
||||
{
|
||||
[Header("阶段信息")]
|
||||
public int phaseIndex; // 0 = 第一阶段
|
||||
public string phaseName;
|
||||
public Color phaseColor; // Boss HP 条颜色(用于区分阶段)
|
||||
|
||||
[Header("可用模式")]
|
||||
public AttackPatternSO[] patterns;
|
||||
|
||||
[Header("休息间隔")]
|
||||
public float minIdleGap; // 两次攻击之间最小空闲(秒)
|
||||
public float maxIdleGap; // 两次攻击之间最大空闲(秒)
|
||||
|
||||
[Header("连招规则")]
|
||||
public int maxComboCount; // 最多连续 n 次不同模式再强制休息
|
||||
public bool allowRepeatPattern; // 是否允许同一模式连续出现
|
||||
|
||||
[Header("阶段过渡特效")]
|
||||
public FeedbackPresetSO transitionFeedback; // 阶段切换时的 MMF_Player 预设
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. BossOrchestrator — 运行时编排器
|
||||
|
||||
`BossOrchestrator` 挂载于 BossBase 所在 GameObject,负责模式选择与执行状态追踪。
|
||||
|
||||
```csharp
|
||||
namespace BaseGames.Enemies.Boss.Patterns
|
||||
{
|
||||
public class BossOrchestrator : MonoBehaviour
|
||||
{
|
||||
[Header("配置")]
|
||||
[SerializeField] BossPhaseConfigSO[] _phases; // 所有阶段配置,按 phaseIndex 排列
|
||||
[SerializeField] TelegraphSystem _telegraph; // 预警组件
|
||||
|
||||
[Header("事件频道")]
|
||||
[SerializeField] IntEventChannelSO _onBossPhaseChanged; // 发布(传入新阶段索引)
|
||||
[SerializeField] VoidEventChannelSO _onBossVulnerable; // 后摇期间发布(玩家可追打提示)
|
||||
[SerializeField] StringEventChannelSO _onPatternStarted; // 发布 patternId(音频/镜头响应)
|
||||
|
||||
// ── 运行时状态 ──
|
||||
BossPhaseConfigSO _currentPhase;
|
||||
AttackPatternSO _currentPattern;
|
||||
PatternState _state;
|
||||
float _stateTimer;
|
||||
int _comboCounter;
|
||||
readonly Dictionary<AttackPatternSO, float> _cooldownTimers = new();
|
||||
|
||||
public bool IsExecutingPattern => _state != PatternState.Idle;
|
||||
public AttackPatternSO CurrentPattern => _currentPattern;
|
||||
|
||||
// ────────────────────────────────────────────
|
||||
// 公开 API(供 BehaviorDesigner Tasks 调用)
|
||||
// ────────────────────────────────────────────
|
||||
|
||||
public void SetPhase(int phaseIndex)
|
||||
{
|
||||
_currentPhase = _phases[phaseIndex];
|
||||
_comboCounter = 0;
|
||||
_onBossPhaseChanged.Raise(phaseIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 选择并开始执行一个合适的攻击模式。
|
||||
/// 返回 false 时表示没有可用模式(AI 应等待后重试)。
|
||||
/// </summary>
|
||||
public bool TryExecutePattern(Vector2 playerPosition)
|
||||
{
|
||||
if (_state != PatternState.Idle) return false;
|
||||
|
||||
var pattern = SelectPattern(playerPosition);
|
||||
if (pattern == null) return false;
|
||||
|
||||
StartPattern(pattern);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void AbortCurrentPattern()
|
||||
{
|
||||
StopAllCoroutines();
|
||||
_state = PatternState.Idle;
|
||||
_currentPattern = null;
|
||||
}
|
||||
|
||||
// ────────────────────────────────────────────
|
||||
// 内部逻辑
|
||||
// ────────────────────────────────────────────
|
||||
|
||||
AttackPatternSO SelectPattern(Vector2 playerPos)
|
||||
{
|
||||
float distToPlayer = Vector2.Distance(transform.position, playerPos);
|
||||
bool playerAbove = playerPos.y > transform.position.y + 0.5f;
|
||||
|
||||
// 1. 筛选:满足条件 + 冷却完毕
|
||||
var candidates = new List<(AttackPatternSO pat, int weight)>();
|
||||
foreach (var p in _currentPhase.patterns)
|
||||
{
|
||||
if (!IsCooledDown(p)) continue;
|
||||
if (!CheckConditions(p, distToPlayer, playerAbove)) continue;
|
||||
if (!_currentPhase.allowRepeatPattern && p == _currentPattern) continue;
|
||||
candidates.Add((p, p.weight));
|
||||
}
|
||||
if (candidates.Count == 0) return null;
|
||||
|
||||
// 强制休息检查
|
||||
if (_comboCounter >= _currentPhase.maxComboCount) return null;
|
||||
|
||||
// 2. 加权随机选择
|
||||
int totalWeight = candidates.Sum(c => c.weight);
|
||||
int roll = UnityEngine.Random.Range(0, totalWeight);
|
||||
int accumulated = 0;
|
||||
foreach (var (pat, w) in candidates)
|
||||
{
|
||||
accumulated += w;
|
||||
if (roll < accumulated) return pat;
|
||||
}
|
||||
return candidates[^1].pat;
|
||||
}
|
||||
|
||||
void StartPattern(AttackPatternSO pattern)
|
||||
{
|
||||
_currentPattern = pattern;
|
||||
_state = PatternState.Telegraph;
|
||||
_comboCounter++;
|
||||
_cooldownTimers[pattern] = Time.time;
|
||||
_onPatternStarted.Raise(pattern.patternId);
|
||||
StartCoroutine(ExecutePatternRoutine(pattern));
|
||||
}
|
||||
|
||||
IEnumerator ExecutePatternRoutine(AttackPatternSO p)
|
||||
{
|
||||
// ── 预警阶段 ──
|
||||
_telegraph.ShowTelegraph(p.telegraph);
|
||||
yield return new WaitForSeconds(p.telegraphDuration);
|
||||
_telegraph.HideTelegraph();
|
||||
|
||||
// ── 前摇 ──
|
||||
_state = PatternState.Windup;
|
||||
yield return new WaitForSeconds(p.windupDuration);
|
||||
|
||||
// ── 活跃帧(动画事件触发 HitBox,此处设移动曲线)──
|
||||
_state = PatternState.Active;
|
||||
yield return new WaitForSeconds(p.activeDuration);
|
||||
|
||||
// ── 后摇(脆弱期)──
|
||||
_state = PatternState.Recovery;
|
||||
_onBossVulnerable.Raise();
|
||||
yield return new WaitForSeconds(p.recoveryDuration);
|
||||
|
||||
// ── 完毕 ──
|
||||
_state = PatternState.Idle;
|
||||
_currentPattern = null;
|
||||
}
|
||||
|
||||
bool IsCooledDown(AttackPatternSO p)
|
||||
=> !_cooldownTimers.TryGetValue(p, out float last)
|
||||
|| Time.time - last >= p.cooldown;
|
||||
|
||||
bool CheckConditions(AttackPatternSO p, float dist, bool playerAbove)
|
||||
{
|
||||
foreach (var cond in p.activationConditions)
|
||||
{
|
||||
if (!EvaluateCondition(cond, dist, playerAbove)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EvaluateCondition(PatternCondition c, float dist, bool playerAbove)
|
||||
=> c.type switch
|
||||
{
|
||||
ConditionType.InRange => dist >= c.minRange && dist <= c.maxRange,
|
||||
ConditionType.OutOfRange => dist > c.maxRange,
|
||||
ConditionType.PlayerIsAbove => playerAbove,
|
||||
ConditionType.PlayerIsBelow => !playerAbove,
|
||||
_ => true,
|
||||
};
|
||||
|
||||
void Update()
|
||||
{
|
||||
// 冷却定时器自然流逝(cooldownTimers 存储的是开始时间,不需要手动递减)
|
||||
}
|
||||
}
|
||||
|
||||
public enum PatternState { Idle, Telegraph, Windup, Active, Recovery }
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. TelegraphSystem — 预警系统
|
||||
|
||||
Boss 攻击前通过多层视觉/音效预警给玩家反应时间。
|
||||
|
||||
```csharp
|
||||
public class TelegraphSystem : MonoBehaviour
|
||||
{
|
||||
[Header("预警 Prefab")]
|
||||
[SerializeField] SpriteRenderer _flashOverlay; // Boss 躯体 sprite 闪红
|
||||
[SerializeField] GameObject _groundMarkerPrefab; // 地面危险标记(AOE 落点)
|
||||
[SerializeField] GameObject _directionArrowPrefab; // 方向预警箭头(冲刺)
|
||||
[SerializeField] AudioEventSO _telegraphSFX; // 预警音效频道
|
||||
|
||||
public void ShowTelegraph(TelegraphConfig config)
|
||||
{
|
||||
switch (config.type)
|
||||
{
|
||||
case TelegraphType.BodyFlash:
|
||||
StartCoroutine(FlashRoutine(config.flashColor, config.duration));
|
||||
break;
|
||||
case TelegraphType.GroundMarker:
|
||||
SpawnGroundMarker(config.targetPosition, config.radius);
|
||||
break;
|
||||
case TelegraphType.DirectionArrow:
|
||||
ShowDirectionArrow(config.direction);
|
||||
break;
|
||||
case TelegraphType.FullBodyGlow:
|
||||
SetBodyGlow(config.glowColor, config.duration);
|
||||
break;
|
||||
}
|
||||
_telegraphSFX?.Raise();
|
||||
}
|
||||
|
||||
public void HideTelegraph()
|
||||
{
|
||||
_flashOverlay.color = Color.white;
|
||||
// 隐藏所有活跃的地面标记 / 方向箭头
|
||||
}
|
||||
|
||||
// ... 各预警类型实现
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct TelegraphConfig
|
||||
{
|
||||
public TelegraphType type;
|
||||
public Color flashColor; // BodyFlash / FullBodyGlow 颜色
|
||||
public float duration; // 闪烁/发光持续时长
|
||||
public Vector2 targetPosition; // GroundMarker 目标位置
|
||||
public float radius; // GroundMarker 半径
|
||||
public Vector2 direction; // DirectionArrow 方向
|
||||
}
|
||||
|
||||
public enum TelegraphType
|
||||
{
|
||||
None,
|
||||
BodyFlash, // Boss 躯体快速变色闪烁
|
||||
GroundMarker, // 地面出现危险区域标记(红色圆圈)
|
||||
DirectionArrow, // 在 Boss 前方显示冲刺方向箭头
|
||||
FullBodyGlow, // Boss 全身发光(强攻击专用,通常配合音效)
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 阶段转换规则
|
||||
|
||||
```csharp
|
||||
[CreateAssetMenu(menuName = "Enemies/Boss/PhaseTransitionRule")]
|
||||
public class PhaseTransitionRuleSO : ScriptableObject
|
||||
{
|
||||
[Header("触发条件")]
|
||||
[Range(0f, 1f)]
|
||||
public float hpThreshold; // HP 降到此比例以下触发
|
||||
|
||||
[Header("目标阶段")]
|
||||
public int targetPhaseIndex;
|
||||
|
||||
[Header("过渡演出")]
|
||||
public float invincibilityDuration; // 过渡期间无敌时长(Boss 播放嘲讽/变身动画)
|
||||
public bool healPartial; // 是否恢复部分 HP(如恢复至下一阶段起始 HP)
|
||||
[Range(0f, 1f)]
|
||||
public float partialHealAmount; // 恢复到 HP 总量的 x%
|
||||
}
|
||||
```
|
||||
|
||||
**BossBase 集成**(在 `06_EnemySystem.md §5 BossBase` 中追加):
|
||||
|
||||
```csharp
|
||||
// BossBase.cs — 扩展阶段切换逻辑
|
||||
[SerializeField] PhaseTransitionRuleSO[] _transitionRules;
|
||||
[SerializeField] BossOrchestrator _orchestrator;
|
||||
|
||||
protected override void OnHPChanged(int newHP)
|
||||
{
|
||||
float ratio = (float)newHP / _stats.maxHP;
|
||||
foreach (var rule in _transitionRules)
|
||||
{
|
||||
if (ratio <= rule.hpThreshold && !_triggeredPhases.Contains(rule.targetPhaseIndex))
|
||||
{
|
||||
_triggeredPhases.Add(rule.targetPhaseIndex);
|
||||
StartCoroutine(ExecutePhaseTransition(rule));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator ExecutePhaseTransition(PhaseTransitionRuleSO rule)
|
||||
{
|
||||
// 1. 进入无敌状态
|
||||
SetInvincible(true);
|
||||
_orchestrator.AbortCurrentPattern();
|
||||
|
||||
// 2. 播放过渡演出反馈(MMF_Player: 画面震动 + 色彩分离)
|
||||
_transitionFeedback?.PlayFeedbacks();
|
||||
yield return new WaitForSeconds(rule.invincibilityDuration);
|
||||
|
||||
// 3. 切换阶段
|
||||
_orchestrator.SetPhase(rule.targetPhaseIndex);
|
||||
SetInvincible(false);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 内置攻击模式类型
|
||||
|
||||
### 6.1 近战冲刺(MeleeLunge)
|
||||
|
||||
```
|
||||
Telegraph: DirectionArrow(朝玩家方向箭头,0.5s)
|
||||
Windup: 0.2s(下蹲姿势)
|
||||
Active: 0.15s(HitBox开启 + Rigidbody2D 沿 movementCurve 冲刺)
|
||||
Recovery: 0.5s(滑步停止,Boss 转向玩家)
|
||||
DamageType: Melee · Knockback: Medium
|
||||
isParryable: ✓
|
||||
推荐 weight: 4 · cooldown: 1.5s
|
||||
```
|
||||
|
||||
### 6.2 投射物连射(ProjectileVolley)
|
||||
|
||||
```
|
||||
Telegraph: BodyFlash(橙色,0.6s)
|
||||
Windup: 0.3s(举起武器蓄力)
|
||||
Active: 0.8s(动画事件每 0.2s 生成一颗弹射物,共 3~5 颗)
|
||||
Recovery: 0.4s
|
||||
DamageType: Projectile · isParryable: ✓(弹射物可弹反)
|
||||
推荐 weight: 3 · cooldown: 3s
|
||||
```
|
||||
|
||||
### 6.3 范围打击(AreaDenial)
|
||||
|
||||
```
|
||||
Telegraph: GroundMarker(玩家脚下红圈,0.8s)
|
||||
Windup: 0.4s(跳跃升空)
|
||||
Active: 0.1s(砸地,生成范围 HitBox)
|
||||
Recovery: 0.6s(落地后摇)
|
||||
DamageType: Melee · AoE · isParryable: ✗
|
||||
推荐 weight: 2 · cooldown: 4s
|
||||
条件: InRange(0, 4)
|
||||
```
|
||||
|
||||
### 6.4 全屏横扫(HorizontalSweep)
|
||||
|
||||
```
|
||||
Telegraph: FullBodyGlow(红色,1.0s)
|
||||
Windup: 0.5s
|
||||
Active: 0.3s(持续横向 HitBox 覆盖全屏宽)
|
||||
Recovery: 0.8s(Boss 喘息)
|
||||
DamageType: Melee · Heavy · isParryable: ✗
|
||||
推荐 weight: 1 · cooldown: 8s
|
||||
条件: HPBelow(0.4)(仅在第二阶段以下使用)
|
||||
```
|
||||
|
||||
### 6.5 多段连击(MultiHitCombo)
|
||||
|
||||
```
|
||||
Telegraph: BodyFlash(白色,0.3s)
|
||||
Windup: 0.1s
|
||||
Active: 1.2s(3次HitBox依次开启,间隔0.3s,最后一击可弹反)
|
||||
Recovery: 0.6s
|
||||
DamageType: Melee · Light(1), Light(1), Medium(2)
|
||||
isParryable: 第3击 ✓
|
||||
推荐 weight: 5 · cooldown: 2s
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Boss 原型模板
|
||||
|
||||
### 7.1 敏捷近战 Boss(AgileKnight)
|
||||
|
||||
**设计核心**:高移动速度、多次冲刺、强调弹反互动。
|
||||
|
||||
```
|
||||
阶段 1(HP 100%~50%):
|
||||
模式集: MeleeLunge(w4) · MultiHitCombo(w5) · ProjectileVolley(w2)
|
||||
IdleGap: 0.8~1.5s · MaxCombo: 3
|
||||
|
||||
阶段 2(HP 50%~0%):
|
||||
模式集: MeleeLunge(w6, cooldown减半) · MultiHitCombo(w5) · HorizontalSweep(w2, 仅HP<30%)
|
||||
IdleGap: 0.3~1.0s · MaxCombo: 4
|
||||
过渡: 1.5s无敌 + MMF 色调变红 + 速度提升 1.4×
|
||||
```
|
||||
|
||||
### 7.2 远程投射 Boss(SorcererBoss)
|
||||
|
||||
**设计核心**:与玩家保持距离、多种弹道类型、Arena 控制。
|
||||
|
||||
```
|
||||
阶段 1(HP 100%~60%):
|
||||
模式集: ProjectileVolley(w5) · AreaDenial(w3)
|
||||
条件: OutOfRange(5) 时强制使用 TeleportBehindPlayer 模式
|
||||
IdleGap: 1.0~2.0s
|
||||
|
||||
阶段 2(HP 60%~0%):
|
||||
新增模式: HomingProjectileSpray(向玩家发射3颗追踪弹)
|
||||
IdleGap: 0.6~1.5s
|
||||
过渡: 传送至场地中央 + FullBodyGlow 2s + 特殊动画
|
||||
```
|
||||
|
||||
### 7.3 巨型多阶段 Boss(ColossalBoss)
|
||||
|
||||
**设计核心**:3个阶段、每阶段改变整体行为模式、标志性大招。
|
||||
|
||||
```
|
||||
阶段 1(HP 100%~70%):
|
||||
模式集: GroundSlam · MeleeLunge
|
||||
弱点部位: HurtBox 仅在头部
|
||||
|
||||
阶段 2(HP 70%~35%):
|
||||
新增模式: WallJump + AreaDenial组合(Boss跳墙后俯冲)
|
||||
弱点部位: 头部 + 双手(3个 HurtBox)
|
||||
|
||||
阶段 3(HP 35%~0%):
|
||||
HorizontalSweep + ProjectileVolley 组合使用
|
||||
IdleGap 减至 0.3s
|
||||
背景音乐切换至最终阶段曲
|
||||
弱点部位: 全身开放
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. BehaviorDesigner 集成
|
||||
|
||||
### 自定义 Action Tasks
|
||||
|
||||
```csharp
|
||||
// AI/Actions/Boss/ExecutePatternAction.cs
|
||||
[TaskCategory("Boss/Orchestrator")]
|
||||
[TaskDescription("请求编排器执行一个攻击模式。成功 = 找到并开始了模式;失败 = 无可用模式(需等待)")]
|
||||
public class ExecutePatternAction : Action
|
||||
{
|
||||
[RequiredField] public SharedGameObject bossGO;
|
||||
[RequiredField] public SharedTransform playerTransform;
|
||||
|
||||
BossOrchestrator _orchestrator;
|
||||
|
||||
public override void OnStart()
|
||||
=> _orchestrator = bossGO.Value.GetComponent<BossOrchestrator>();
|
||||
|
||||
public override TaskStatus OnUpdate()
|
||||
{
|
||||
if (_orchestrator.IsExecutingPattern)
|
||||
return TaskStatus.Running;
|
||||
|
||||
bool started = _orchestrator.TryExecutePattern(playerTransform.Value.position);
|
||||
return started ? TaskStatus.Running : TaskStatus.Failure;
|
||||
}
|
||||
}
|
||||
|
||||
// AI/Actions/Boss/SetBossPhaseAction.cs
|
||||
[TaskCategory("Boss/Orchestrator")]
|
||||
public class SetBossPhaseAction : Action
|
||||
{
|
||||
public SharedInt phaseIndex;
|
||||
BossOrchestrator _orchestrator;
|
||||
|
||||
public override void OnStart()
|
||||
{
|
||||
_orchestrator = GetComponent<BossOrchestrator>();
|
||||
_orchestrator.SetPhase(phaseIndex.Value);
|
||||
}
|
||||
|
||||
public override TaskStatus OnUpdate() => TaskStatus.Success;
|
||||
}
|
||||
|
||||
// AI/Conditions/Boss/IsPatternComplete.cs
|
||||
[TaskCategory("Boss/Orchestrator")]
|
||||
[TaskDescription("检查编排器是否已完成当前模式(处于 Idle 状态)")]
|
||||
public class IsPatternComplete : Conditional
|
||||
{
|
||||
BossOrchestrator _orchestrator;
|
||||
|
||||
public override void OnStart()
|
||||
=> _orchestrator = GetComponent<BossOrchestrator>();
|
||||
|
||||
public override TaskStatus OnUpdate()
|
||||
=> _orchestrator.IsExecutingPattern ? TaskStatus.Failure : TaskStatus.Success;
|
||||
}
|
||||
```
|
||||
|
||||
### 典型 Boss 行为树结构
|
||||
|
||||
```
|
||||
Boss BehaviorTree
|
||||
└── Selector(优先检查阶段切换,再执行攻击)
|
||||
├── Sequence(阶段切换检查)
|
||||
│ ├── Conditional: IsBossHPBelow(0.5) && !IsPhase2Active
|
||||
│ └── Action: SetBossPhaseAction(phaseIndex=1)
|
||||
│
|
||||
└── Sequence(攻击循环)
|
||||
├── Action: UpdatePlayerPosition (更新黑板变量)
|
||||
├── Action: FacePlayer (转向玩家)
|
||||
├── Selector(执行攻击或等待)
|
||||
│ ├── Action: ExecutePatternAction(尝试执行模式)
|
||||
│ └── Action: WaitRandom(0.3, 1.0)(无可用模式时等待)
|
||||
└── Action: IsPatternComplete (等待模式完成再循环)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. 事件频道
|
||||
|
||||
| 频道资产 | 类型 | 发布方 | 主要订阅方 |
|
||||
|---------|------|--------|----------|
|
||||
| `OnBossPhaseChanged.asset` | `IntEventChannelSO` | `BossOrchestrator` | `BGMController`(切音乐)、`BossHPBar`(切颜色)、`CameraStateController`(切镜头) |
|
||||
| `OnBossVulnerable.asset` | `VoidEventChannelSO` | `BossOrchestrator` | `UIManager`(显示"追打!"提示)、`PlayerFeedback`(提示音效)|
|
||||
| `OnBossPatternStarted.asset` | `StringEventChannelSO` | `BossOrchestrator` | `AudioManager`(模式专属音效)、`CameraStateController`(镜头跟踪模式) |
|
||||
| `OnBossDefeated.asset` | `StringEventChannelSO` | `BossBase.OnDeath()` | `GameManager`、`ProgressionSystem`、`CutsceneManager` |
|
||||
|
||||
---
|
||||
|
||||
## 10. 编辑器工具
|
||||
|
||||
### BossPatternPreview — Inspector 实时预览
|
||||
|
||||
`AttackPatternSO` 自定义 Inspector 显示时序甘特图:
|
||||
|
||||
```
|
||||
┌─ AttackPatternSO: MeleeLunge ──────────────────────────────┐
|
||||
│ 时序(总计 1.35s): │
|
||||
│ [预警████0.5s][前摇██0.2s][活跃█0.15s][后摇█████0.5s] │
|
||||
│ ───────────────────────────────────────────────────── │
|
||||
│ 伤害: 2 · 可弹反: ✓ · 权重: 4 · 冷却: 1.5s │
|
||||
│ 条件: 无 │
|
||||
│ ───────────────────────────────────────────────────── │
|
||||
│ [在 Scene 中预览预警] [在 Game 视图模拟执行] │
|
||||
└────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### BossPhaseFlowGraph — EditorWindow
|
||||
|
||||
`Tools > Zeling > Boss Phase Flow` 显示:
|
||||
- 所有 Boss Prefab 的阶段节点图
|
||||
- HP 阈值触发箭头
|
||||
- 每个阶段的模式列表(权重可视化为饼图)
|
||||
- 点击模式节点 → 跳转到对应 `AttackPatternSO`
|
||||
Reference in New Issue
Block a user