Files
zeling_v2/Assets/_Game/Scripts/Enemies/Boss/BossResource.cs
T
joywayerandClaude Opus 5 3665504a58 feat(ai): 新增 IBossControl facet——Boss 阶段状态经 IAiContext 供图读取
非 Boss 敌人访问 IAiContext.Boss 显式抛 InvalidOperationException,
不返回空对象掩盖小怪图误挂 Boss 边的错误。BossResource 补 IsFull 供图条件边判定。

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

109 lines
4.1 KiB
C#

using UnityEngine;
using BaseGames.Enemies;
namespace BaseGames.Boss
{
/// <summary>
/// Boss 自身资源(如愤怒值)运行时组件。
/// 根据 <see cref="BossResourceConfigSO"/> 配置:
/// - 每帧以 <see cref="BossResourceConfigSO.passiveRate"/> 自动积累或消耗。
/// - 受击时增加 <see cref="BossResourceConfigSO.onTakeDamageGain"/>。
/// - 技能使用时增加 <see cref="BossResourceConfigSO.onSkillUseGain"/>。
/// - 满值时若 <see cref="BossResourceConfigSO.autoTriggerOnFull"/>,自动让 BossBase 执行配置的技能。
/// </summary>
public sealed class BossResource : MonoBehaviour
{
[SerializeField] private BossResourceConfigSO _config;
[SerializeField] private BossBase _boss;
private float _currentValue;
private bool _fullTriggered;
/// <summary>当前资源值(0 ~ config.maxValue)。</summary>
public float CurrentValue => _currentValue;
/// <summary>当前资源值归一化(0~1)。</summary>
public float NormalizedValue => _config != null && _config.maxValue > 0f
? _currentValue / _config.maxValue : 0f;
/// <summary>资源是否已达上限(供 AI 图条件边判定"可放大招")。</summary>
public bool IsFull => _config != null && _config.maxValue > 0f
&& _currentValue >= _config.maxValue;
private void Awake()
{
if (_boss == null) _boss = GetComponentInParent<BossBase>();
if (_config == null)
{
Debug.LogError("[BossResource] 未配置 BossResourceConfigSO。", this);
enabled = false;
return;
}
_currentValue = _config.startValue;
}
private void Update()
{
if (_config == null || !_boss.IsAlive) return;
if (_config.passiveRate != 0f)
AddValue(_config.passiveRate * Time.deltaTime);
}
// ── 外部触发 ──────────────────────────────────────────────────────────
/// <summary>Boss 受击时调用。由 BossBase.TakeDamage 覆写钩子触发。</summary>
public void OnBossTakeDamage()
{
if (_config == null) return;
AddValue(_config.onTakeDamageGain);
}
/// <summary>Boss 使用技能时调用。由 BossBase.UseBossSkill 触发。</summary>
public void OnBossUseSkill()
{
if (_config == null) return;
AddValue(_config.onSkillUseGain);
}
/// <summary>直接设置资源值(外部强制赋值,跳过满值触发)。</summary>
public void SetValue(float value)
{
_currentValue = Mathf.Clamp(value, 0f, _config != null ? _config.maxValue : float.MaxValue);
}
// ── 内部 ──────────────────────────────────────────────────────────────
private void AddValue(float delta)
{
float prev = _currentValue;
_currentValue = Mathf.Clamp(_currentValue + delta, 0f, _config.maxValue);
// 满值触发(从未满→满时只触发一次)
if (_config.autoTriggerOnFull &&
_currentValue >= _config.maxValue &&
prev < _config.maxValue &&
!_fullTriggered)
{
_fullTriggered = true;
OnReachFull();
}
if (_currentValue < _config.maxValue)
_fullTriggered = false;
}
private void OnReachFull()
{
if (_config.fullTriggerSkill == null || _boss == null) return;
_boss.UseBossSkill(_config.fullTriggerSkill.skillId);
if (_config.resetValueAfterTrigger > 0f)
_currentValue = _config.resetValueAfterTrigger;
else
_currentValue = 0f;
}
}
}