- 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.
69 lines
2.6 KiB
C#
69 lines
2.6 KiB
C#
#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
|