diff --git a/Assets/Scripts/Bootstrap/BootSceneController.cs b/Assets/Scripts/Bootstrap/BootSceneController.cs
index 3c9a2b99..239d8b0c 100644
--- a/Assets/Scripts/Bootstrap/BootSceneController.cs
+++ b/Assets/Scripts/Bootstrap/BootSceneController.cs
@@ -14,9 +14,16 @@ namespace Bootstrap
[SerializeField] private string mainMenuSceneName = "MainMenu";
[SerializeField] private float minDelayAfterBoot = 0.5f; // Small delay after boot to ensure smooth transition
[SerializeField] private bool debugMode = false;
-
+
+ // Progress distribution between bootstrap and scene loading
+ [SerializeField, Range(0.1f, 0.9f)] private float bootProgressWeight = 0.5f; // Default 50/50 split
+
+ private enum LoadingPhase { Bootstrap, SceneLoading }
+ private LoadingPhase _currentPhase = LoadingPhase.Bootstrap;
+
private bool _bootComplete = false;
private bool _hasStartedLoading = false;
+ private float _sceneLoadingProgress = 0f;
private void Start()
{
@@ -29,12 +36,12 @@ namespace Bootstrap
return;
}
- // Show the loading screen immediately
+ // Show the loading screen immediately with our combined progress provider
LoadingScreenController.Instance.ShowLoadingScreen(
- // Use the CustomBoot progress as the progress provider
- progressProvider: () => CustomBoot.CurrentProgress,
- // When loading screen is fully hidden, load main menu
- onComplete: () => LoadMainMenu()
+ progressProvider: GetCombinedProgress,
+ onComplete: () => {
+ Debug.Log("[BootSceneController] Loading screen fully hidden, boot sequence completed");
+ }
);
// Start the boot process if not already initialized
@@ -73,17 +80,38 @@ namespace Bootstrap
}
}
+ ///
+ /// Progress provider that combines bootstrap and scene loading progress
+ ///
+ private float GetCombinedProgress()
+ {
+ switch (_currentPhase)
+ {
+ case LoadingPhase.Bootstrap:
+ // Scale bootstrap progress from 0 to bootProgressWeight
+ return CustomBoot.CurrentProgress * bootProgressWeight;
+
+ case LoadingPhase.SceneLoading:
+ // Scale scene loading progress from bootProgressWeight to 1.0
+ return bootProgressWeight + (_sceneLoadingProgress * (1f - bootProgressWeight));
+
+ default:
+ return 0f;
+ }
+ }
+
private void OnBootProgressChanged(float progress)
{
if (debugMode)
{
- Debug.Log($"[BootSceneController] Boot progress: {progress:P0}");
+ Debug.Log($"[BootSceneController] Bootstrap progress: {progress:P0}, Combined: {GetCombinedProgress():P0}");
}
}
private void LogDebugInfo()
{
- Debug.Log($"[BootSceneController] Debug - Boot Progress: {CustomBoot.CurrentProgress:P0}, Boot Complete: {_bootComplete}, Loading Started: {_hasStartedLoading}");
+ Debug.Log($"[BootSceneController] Debug - Phase: {_currentPhase}, Bootstrap: {CustomBoot.CurrentProgress:P0}, " +
+ $"Scene: {_sceneLoadingProgress:P0}, Combined: {GetCombinedProgress():P0}, Boot Complete: {_bootComplete}");
}
private void OnBootCompleted()
@@ -94,34 +122,56 @@ namespace Bootstrap
Debug.Log("[BootSceneController] Boot process completed");
_bootComplete = true;
- // After a small delay, tell the loading screen we're done
+ // After a small delay, start loading the main menu
// This prevents jerky transitions if boot happens very quickly
- Invoke(nameof(CompleteLoadingScreen), minDelayAfterBoot);
+ Invoke(nameof(StartLoadingMainMenu), minDelayAfterBoot);
}
- private void CompleteLoadingScreen()
+ private void StartLoadingMainMenu()
{
- Debug.Log("[BootSceneController] Hiding loading screen");
-
- // Tell loading screen that loading is complete
- if (LoadingScreenController.Instance != null)
- {
- LoadingScreenController.Instance.HideLoadingScreen();
- }
- }
-
- private async void LoadMainMenu()
- {
- // Prevent multiple scene loads
if (_hasStartedLoading)
return;
_hasStartedLoading = true;
+ _currentPhase = LoadingPhase.SceneLoading;
+ LoadMainMenu();
+ }
+
+ private async void LoadMainMenu()
+ {
Debug.Log($"[BootSceneController] Loading main menu scene: {mainMenuSceneName}");
- // Load the main menu scene
- var progress = new Progress(p => Debug.Log($"Loading main menu: {p * 100:F0}%"));
- await SceneManagerService.Instance.SwitchSceneAsync(mainMenuSceneName, progress);
+ try
+ {
+ // Initialize scene loading progress to 0 to ensure proper remapping
+ _sceneLoadingProgress = 0f;
+
+ // Create a progress object that remaps scene loading progress (0-1) to our second phase range
+ var progress = new Progress(p => {
+ // Store the raw scene loading progress (0-1)
+ _sceneLoadingProgress = p;
+
+ if (debugMode)
+ {
+ Debug.Log($"[BootSceneController] Scene loading raw: {p:P0}, Combined: {GetCombinedProgress():P0}");
+ }
+ });
+
+ // Load the scene but don't auto-hide loading screen (we're managing that ourselves)
+ await SceneManagerService.Instance.SwitchSceneAsync(mainMenuSceneName, progress, autoHideLoadingScreen: false);
+
+ // Ensure progress is complete
+ _sceneLoadingProgress = 1f;
+
+ // Scene is fully loaded, we can now hide the loading screen
+ LoadingScreenController.Instance.HideLoadingScreen();
+ }
+ catch (Exception e)
+ {
+ Debug.LogError($"[BootSceneController] Error loading main menu: {e.Message}");
+ // Still try to hide the loading screen even if there was an error
+ LoadingScreenController.Instance.HideLoadingScreen();
+ }
}
}
}
diff --git a/Assets/Scripts/Cinematics/CinematicsManager.cs b/Assets/Scripts/Cinematics/CinematicsManager.cs
index e8dbf1a5..884090d1 100644
--- a/Assets/Scripts/Cinematics/CinematicsManager.cs
+++ b/Assets/Scripts/Cinematics/CinematicsManager.cs
@@ -1,3 +1,4 @@
+using System;
using System.Collections.Generic;
using Core;
using UnityEngine;
@@ -146,11 +147,11 @@ namespace Cinematics
_addressableHandles.Clear();
}
- private void Awake()
+ private void Start()
{
- PlayStartCinematicOnGameLoad();
+
}
-
+
///
/// Loads a cinematic asynchronously while showing a loading screen, then plays it
///
diff --git a/Assets/Scripts/Core/SceneManagerService.cs b/Assets/Scripts/Core/SceneManagerService.cs
index 3ecc6a8f..c36e7405 100644
--- a/Assets/Scripts/Core/SceneManagerService.cs
+++ b/Assets/Scripts/Core/SceneManagerService.cs
@@ -264,14 +264,25 @@ namespace Core
// Tracks the currently loaded gameplay scene (not persistent/bootstrapper)
public string CurrentGameplayScene { get; private set; } = "MainMenu";
- public async Task ReloadCurrentScene(IProgress progress = null)
+ public async Task ReloadCurrentScene(IProgress progress = null, bool autoHideLoadingScreen = true)
{
- await SwitchSceneAsync(CurrentGameplayScene, progress);
+ await SwitchSceneAsync(CurrentGameplayScene, progress, autoHideLoadingScreen);
}
- // Switches from current gameplay scene to a new one
- public async Task SwitchSceneAsync(string newSceneName, IProgress progress = null)
+ ///
+ /// Switches from current gameplay scene to a new one
+ ///
+ /// Name of the scene to load
+ /// Optional progress reporter
+ /// Whether to automatically hide the loading screen when complete. If false, caller must hide it manually.
+ public async Task SwitchSceneAsync(string newSceneName, IProgress progress = null, bool autoHideLoadingScreen = true)
{
+ // Show loading screen at the start (whether using auto-hide or not)
+ if (_loadingScreen != null && !_loadingScreen.IsActive)
+ {
+ _loadingScreen.ShowLoadingScreen();
+ }
+
// Remove all AstarPath (A* Pathfinder) singletons before loading the new scene
var astarPaths = FindObjectsByType(FindObjectsSortMode.None);
foreach (var astar in astarPaths)
@@ -304,6 +315,12 @@ namespace Core
await LoadSceneAsync(newSceneName, progress);
// Update tracker
CurrentGameplayScene = newSceneName;
+
+ // Only hide the loading screen if autoHideLoadingScreen is true
+ if (autoHideLoadingScreen && _loadingScreen != null)
+ {
+ _loadingScreen.HideLoadingScreen();
+ }
}
}
}