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:
68
Assets/_Game/Scripts/Enemies/AI/BD_WaitUntilAbilityEnd.cs
Normal file
68
Assets/_Game/Scripts/Enemies/AI/BD_WaitUntilAbilityEnd.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
#if GRAPH_DESIGNER
|
||||
using UnityEngine;
|
||||
using Opsive.BehaviorDesigner.Runtime.Tasks;
|
||||
using Opsive.BehaviorDesigner.Runtime.Tasks.Actions;
|
||||
using BaseGames.Enemies;
|
||||
using BaseGames.Enemies.Abilities;
|
||||
|
||||
namespace BaseGames.Enemies.AI
|
||||
{
|
||||
/// <summary>
|
||||
/// BD Action:等待指定能力执行结束后返回 Success。
|
||||
/// 适用于需要同步等待某个由外部触发的能力(而非本节点触发)的场景。
|
||||
///
|
||||
/// 返回 Running:能力正在执行。
|
||||
/// 返回 Success:能力执行完毕(IsRunning = false)。
|
||||
/// 返回 Failure:能力不存在,或超时保护触发。
|
||||
///
|
||||
/// 典型用法:Sequence [ BD_UseAbility(A) → BD_WaitUntilAbilityEnd(B) ] 等待 B 被 A 内部链式触发后结束。
|
||||
/// </summary>
|
||||
[TaskName("Wait Until Ability End")]
|
||||
[TaskCategory("BaseGames/Enemy/Combat")]
|
||||
[TaskDescription("等待指定能力执行完成后返回 Success")]
|
||||
public sealed class BD_WaitUntilAbilityEnd : Action
|
||||
{
|
||||
[Tooltip("可直接拖拽 EnemyAbilitySO 资产(推荐),或填写裸字符串 ID 作为兜底")]
|
||||
[SerializeField] private EnemyAbilitySO m_AbilitySO;
|
||||
[SerializeField] private string m_AbilityId = "";
|
||||
|
||||
[Tooltip("超时保护(秒);0 = 永不超时")]
|
||||
[SerializeField, Min(0f)] private float m_Timeout = 5f;
|
||||
|
||||
private EnemyBase _enemy;
|
||||
private EnemyAbilityBase _ability;
|
||||
private float _deadline;
|
||||
|
||||
public override void OnAwake() => _enemy = GetComponent<EnemyBase>();
|
||||
|
||||
public override void OnStart()
|
||||
{
|
||||
_ability = null;
|
||||
_deadline = m_Timeout > 0f ? Time.time + m_Timeout : float.MaxValue;
|
||||
|
||||
if (_enemy == null) return;
|
||||
string id = m_AbilitySO != null ? m_AbilitySO.abilityId : m_AbilityId;
|
||||
if (!string.IsNullOrEmpty(id))
|
||||
_ability = _enemy.Abilities?.Get(id);
|
||||
}
|
||||
|
||||
public override TaskStatus OnUpdate()
|
||||
{
|
||||
if (_ability == null) return TaskStatus.Failure;
|
||||
|
||||
if (Time.time >= _deadline)
|
||||
{
|
||||
Debug.LogWarning($"[BD_WaitUntilAbilityEnd] 能力 '{_ability.Config?.abilityId}' 超时,强制中断", gameObject);
|
||||
// 强制中断仍在运行的能力,防止 HitBox/动画协程泄漏
|
||||
if (_ability.IsRunning)
|
||||
_ability.Interrupt(InterruptReason.ExternalRequest);
|
||||
return TaskStatus.Failure;
|
||||
}
|
||||
|
||||
return _ability.IsRunning ? TaskStatus.Running : TaskStatus.Success;
|
||||
}
|
||||
|
||||
public override void OnEnd() => _ability = null;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user