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:
@@ -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>流式加载预算配置 SO,RoomStreamingManager 与 TransitionDirector 均依赖此资产。</summary>
|
||||
public const string DataStreamingBudgetConfig = "Config/StreamingBudgetConfig";
|
||||
|
||||
/// <summary>
|
||||
/// Addressable Label 常量(用于批量加载与预热)。
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
28
Assets/_Game/Scripts/Core/ITransitionDirector.cs
Normal file
28
Assets/_Game/Scripts/Core/ITransitionDirector.cs
Normal 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 状态),可执行无缝切换。
|
||||
/// 若返回 false,SceneService 将退回带黑屏的 Room 过渡。
|
||||
/// </summary>
|
||||
bool CanHandleSeamless(string targetSceneName);
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user