feat: Implement Room Streaming System
- Add RoomStreamingManager to manage room loading and unloading based on player proximity. - Create StreamingBudgetConfigSO for memory and performance budgeting of the streaming system. - Introduce TransitionDirector to handle seamless and atmospheric fade transitions between rooms. - Develop WorldGraph to represent room connectivity and facilitate neighbor queries and distance calculations. - Implement RoomNode and RoomEdge classes to structure room data and connections.
This commit is contained in:
104
Assets/_Game/Scripts/Enemies/Boss/BossResource.cs
Normal file
104
Assets/_Game/Scripts/Enemies/Boss/BossResource.cs
Normal file
@@ -0,0 +1,104 @@
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user