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:
2026-05-23 19:10:29 +08:00
parent 81c326af53
commit a1b4e629aa
165 changed files with 7904 additions and 313 deletions

View File

@@ -51,7 +51,10 @@ namespace BaseGames.Core.Assets
public const string PrefabWeaponSoulStaff = "WPN_SoulStaff";
// ── Config ScriptableObjects ─────────────────────────────────────
public const string DataFootstepCatalog = "Config/FootstepCatalog";
public const string DataFootstepCatalog = "Config/FootstepCatalog";
/// <summary>流式加载预算配置 SORoomStreamingManager 与 TransitionDirector 均依赖此资产。</summary>
public const string DataStreamingBudgetConfig = "Config/StreamingBudgetConfig";
/// <summary>
/// Addressable Label 常量(用于批量加载与预热)。

View File

@@ -1,7 +1,8 @@
namespace BaseGames.Core.Events
{
/// <summary>
/// 场景过渡类型,决定 <see cref="BaseGames.Core.SceneService"/> 的演出行为。
/// 场景过渡类型,决定 <see cref="BaseGames.Core.SceneService"/>
/// <see cref="BaseGames.Core.ITransitionDirector"/> 的演出行为。
/// </summary>
public enum TransitionType
{
@@ -12,5 +13,14 @@ namespace BaseGames.Core.Events
/// <summary>跨大区域切换。完整淡出,显示加载画面。
/// 适用于地图间传送、返回标题、大区域入口等有明显空间跳跃感的切换。</summary>
Scene,
/// <summary>无缝切换。无任何遮挡目标房间必须已预加载Dormant 状态)。
/// 相机跟随玩家越过边界,视觉上无任何打断感。
/// 若目标房间尚未就绪TransitionDirector 将等待预加载完成后再执行切换(有超时保护)。</summary>
Seamless,
/// <summary>氛围淡入淡出切换。短暂淡出≈0.25 s+ 显示新区域名称 + 淡入。
/// 适用于跨大区域边界、目标房间已预加载的情况,比 Room 有更强的"抵达感"。</summary>
AtmosphericFade,
}
}

View File

@@ -0,0 +1,28 @@
using BaseGames.Core.Events;
namespace BaseGames.Core
{
/// <summary>
/// 过渡导演接口。
/// <para>
/// <see cref="SceneService"/> 在处理 <see cref="SceneLoadRequest"/> 时,
/// 若过渡类型为 <see cref="TransitionType.Seamless"/> 或 <see cref="TransitionType.AtmosphericFade"/>
/// 则通过 ServiceLocator 查找此接口并委托处理。
/// 若未找到实现(非流式模式),则退回原有淡出加载流程。
/// </para>
/// </summary>
public interface ITransitionDirector
{
/// <summary>
/// 处理过渡请求。由 SceneService 在确认过渡类型后调用。
/// 实现方负责完整的过渡流程(激活目标房间、相机切换、播放演出等)。
/// </summary>
void HandleTransition(SceneLoadRequest request);
/// <summary>
/// 查询目标场景是否已预加载完毕(处于 Dormant 状态),可执行无缝切换。
/// 若返回 falseSceneService 将退回带黑屏的 Room 过渡。
/// </summary>
bool CanHandleSeamless(string targetSceneName);
}
}

View File

@@ -70,7 +70,29 @@ namespace BaseGames.Core
private void OnDisable() => _subscriptions.Clear();
private void HandleSceneLoadRequest(SceneLoadRequest request)
=> StartCoroutine(LoadSceneCoroutine(request));
{
// Seamless / AtmosphericFade 由 ITransitionDirector 处理(需要预加载支持)
if (request.TransitionType == TransitionType.Seamless ||
request.TransitionType == TransitionType.AtmosphericFade)
{
var director = ServiceLocator.GetOrDefault<ITransitionDirector>();
if (director != null)
{
// TransitionDirector 内部处理"立即切换"与"等待预加载后切换"两条路径
director.HandleTransition(request);
return;
}
// 未注册 ITransitionDirector非流式模式降级为 Room 过渡
Debug.LogWarning($"[SceneService] 未找到 ITransitionDirector{request.TransitionType} 降级为 Room 过渡。");
var degraded = request;
degraded.TransitionType = TransitionType.Room;
StartCoroutine(LoadSceneCoroutine(degraded));
return;
}
StartCoroutine(LoadSceneCoroutine(request));
}
public IEnumerator LoadSceneCoroutine(SceneLoadRequest request)
{