Files
zeling_v2/Assets/_Game/Scripts/Enemies/Boss/ChaoFengKnockdownCounter.cs
T
joywayerandClaude Opus 5 d3013b1053 refactor(enemy)!: 删除旧 Boss 轨 9 个脚本
BossSkillSO / AttackPatternSO / SkillSequenceSO / BossSkillExecutor /
BossSkillTypes / WeakPointSystem / TelegraphSystem / BossSkillModule /
BossSkillSequenceWindow,连同 Patterns 独立程序集(BaseGames.Enemies.Boss.Patterns.asmdef,
已核实无任何 asmdef 按名或按 GUID 引用它)整包移除。

删前先清两处引用:
- ChaoFengKnockdownCounter 击落打断改走 _boss.Abilities.InterruptAll(ExternalRequest)
- EditorScaffoldUtils 命名前缀表删掉两条指向已删类型的死条目(还与 AssetFolderSpec 的 ABL_ 冲突)

判据「有更优替代才删」逐项对应:
- 编排 → EnemyAbilitySO + EnemyAttackSO(归一化时机 / 槽位 HitBox)
- 阶段门 → BossPhaseAbilityGate
- 选招 → EnemyAttackSelector + WeightedRandomAntiRepeat
- 可弹反 → DamageSourceSO.Flags(CanBeParried),HurtBox 已在判定
- 弱点倍率 → HurtBox 自带倍率(原实现的 GetDamageMultiplier 零调用者)
- 预警 → clip 姿态 + 动画事件(TriggerFeedback / PlaySFX 已补接)
- 竞技场联动 → EnemySpawnerOnEvent
- 霸体窗口 → EnemyAttackSO.hasPoiseWindow 四字段

能力资产的编辑器总览视图随 BossSkillModule 一并消失,
后续补 EnemyAbilityModule(优先级低于 AiDefinitionValidator)。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 16:39:57 +08:00

102 lines
3.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Collections;
using Animancer;
using BaseGames.Boss;
using BaseGames.Combat;
using BaseGames.Enemies.Abilities;
using UnityEngine;
namespace BaseGames.Enemies.Boss
{
/// <summary>
/// 嘲风击落计数器(Phase 2)。
/// 由 <see cref="ChaoFengBoss.OnDamageTaken"/> 直接调用 <see cref="OnBossHit"/>
/// 累计命中达到阈值后触发击落序列(下落 → 硬直 → 复位浮空)。
///
/// ⚠️ HurtBox 无公开 OnDamageTaken 事件,必须通过 EnemyBase.OnDamageTaken 虚方法转发。
/// </summary>
public class ChaoFengKnockdownCounter : MonoBehaviour
{
[SerializeField] private int _threshold = 8;
[Header("依赖引用")]
[SerializeField] private ChaoFengBoss _boss;
[SerializeField] private ChaoFengFloatController _floatCtrl;
[Header("击落动画")]
[SerializeField] private ClipTransition _knockdownHitClip;
[Tooltip("击落后硬直动画(复用 Defeat_Pant Clip")]
[SerializeField] private ClipTransition _staggerClip;
[SerializeField] private float _staggerDuration = 3f;
private int _count;
private bool _inKnockdown;
private BaseGames.Core.IGroundedActor _playerGround;
private Transform _cachedPlayer;
/// <summary>
/// 由 <see cref="ChaoFengBoss.OnDamageTaken"/> 调用,累计受击并在达到阈值时触发击落。
/// 仅统计「玩家处于空中」时的命中(设计:空中攻击命中嘲风才计入击落)。
/// </summary>
public void OnBossHit(DamageInfo info)
{
if (_inKnockdown || _boss == null || _boss.CurrentPhase != 1) return;
if (!IsPlayerAirborne()) return; // Q6:仅玩家在空中的命中计数
_count++;
if (_count >= _threshold)
{
_count = 0;
StartCoroutine(KnockdownSequence());
}
}
/// <summary>
/// 通过 Boss 缓存的 PlayerTransform 取玩家的 <see cref="BaseGames.Core.IGroundedActor"/>PlayerMovement 实现),
/// 判定其是否离地。取不到接口时按「空中」处理(保守计数,避免机制失效)。
/// </summary>
private bool IsPlayerAirborne()
{
var player = _boss.PlayerTransform;
if (player == null) return false;
if (!ReferenceEquals(player, _cachedPlayer))
{
_cachedPlayer = player;
_playerGround = player.GetComponentInParent<BaseGames.Core.IGroundedActor>()
?? player.GetComponentInChildren<BaseGames.Core.IGroundedActor>();
}
return _playerGround == null || !_playerGround.IsGrounded;
}
/// <summary>强制结束正在进行中的击落序列(由 ChaoFengBoss.DefeatSequence 调用)。</summary>
public void ForceEnd()
{
StopAllCoroutines();
_inKnockdown = false;
_count = 0;
}
private IEnumerator KnockdownSequence()
{
_inKnockdown = true;
// 击落打断当前正在执行的所有能力(招式统一由能力注册表管理)
_boss.Abilities.InterruptAll(InterruptReason.ExternalRequest);
if (_knockdownHitClip.Clip != null)
_boss.Animancer.Play(_knockdownHitClip);
yield return _floatCtrl.FallDown();
if (_staggerClip.Clip != null)
_boss.Animancer.Play(_staggerClip);
yield return new WaitForSeconds(_staggerDuration);
yield return _floatCtrl.FloatUp();
_inKnockdown = false;
}
}
}