Working scene transitions

This commit is contained in:
Michal Pikulski
2025-10-16 13:42:28 +02:00
parent 49c4d968aa
commit 270877b280
9 changed files with 656 additions and 183 deletions

View File

@@ -3,6 +3,7 @@ using UnityEngine;
using UI;
using Core;
using UnityEngine.SceneManagement;
using Cinematics;
namespace Bootstrap
{
@@ -14,6 +15,7 @@ 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;
[SerializeField] private InitialLoadingScreen initialLoadingScreen; // Reference to our specialized loading screen
// Progress distribution between bootstrap and scene loading
[SerializeField, Range(0.1f, 0.9f)] private float bootProgressWeight = 0.5f; // Default 50/50 split
@@ -29,20 +31,18 @@ namespace Bootstrap
{
Debug.Log("[BootSceneController] Boot scene started");
// Ensure the loading screen controller exists
if (LoadingScreenController.Instance == null)
// Ensure the initial loading screen exists
if (initialLoadingScreen == null)
{
Debug.LogError("[BootSceneController] No LoadingScreenController found in the scene!");
Debug.LogError("[BootSceneController] No InitialLoadingScreen assigned! Please assign it in the inspector.");
return;
}
// Subscribe to the loading screen completion event
initialLoadingScreen.OnLoadingScreenFullyHidden += OnInitialLoadingComplete;
// Show the loading screen immediately with our combined progress provider
LoadingScreenController.Instance.ShowLoadingScreen(
progressProvider: GetCombinedProgress,
onComplete: () => {
Debug.Log("[BootSceneController] Loading screen fully hidden, boot sequence completed");
}
);
initialLoadingScreen.ShowLoadingScreen(GetCombinedProgress);
// Start the boot process if not already initialized
if (!CustomBoot.Initialised)
@@ -68,12 +68,43 @@ namespace Bootstrap
}
}
/// <summary>
/// Called when the initial loading screen is fully hidden
/// </summary>
private void OnInitialLoadingComplete()
{
Debug.Log("[BootSceneController] Initial loading screen fully hidden, boot sequence completed");
// Play the intro cinematic if available
if (CinematicsManager.Instance != null)
{
Debug.Log("[BootSceneController] Attempting to play intro cinematic");
// Use LoadAndPlayCinematic to play the intro sequence
CinematicsManager.Instance.LoadAndPlayCinematic("IntroSequence");
// Immediately unload the StartingScene - no need to wait for cinematic to finish
// since CinematicsManager is bootstrapped and won't be unloaded
UnloadStartingScene();
}
else
{
// If no cinematics manager, unload the StartingScene directly
UnloadStartingScene();
}
}
private void OnDestroy()
{
// Clean up event subscriptions
CustomBoot.OnBootCompleted -= OnBootCompleted;
CustomBoot.OnBootProgressChanged -= OnBootProgressChanged;
if (initialLoadingScreen != null)
{
initialLoadingScreen.OnLoadingScreenFullyHidden -= OnInitialLoadingComplete;
}
if (debugMode)
{
CancelInvoke(nameof(LogDebugInfo));
@@ -146,31 +177,97 @@ namespace Bootstrap
// 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<float>(p => {
// Create a custom progress reporter using a custom class
var progressHandler = new ProgressHandler(value => {
// Store the raw scene loading progress (0-1)
_sceneLoadingProgress = p;
_sceneLoadingProgress = value;
if (debugMode)
{
Debug.Log($"[BootSceneController] Scene loading raw: {p:P0}, Combined: {GetCombinedProgress():P0}");
Debug.Log($"[BootSceneController] Scene loading raw: {value: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);
// Step 1: Additively load the main menu scene - don't unload StartingScene yet
var op = SceneManager.LoadSceneAsync(mainMenuSceneName, LoadSceneMode.Additive);
// Disable scene activation until we're ready to show it
op.allowSceneActivation = true;
// Track progress while loading
while (!op.isDone)
{
progressHandler.ReportProgress(op.progress);
await System.Threading.Tasks.Task.Yield();
}
// Update the current gameplay scene in SceneManagerService
SceneManagerService.Instance.CurrentGameplayScene = mainMenuSceneName;
// Ensure progress is complete
_sceneLoadingProgress = 1f;
// Scene is fully loaded, we can now hide the loading screen
LoadingScreenController.Instance.HideLoadingScreen();
// Step 2: Scene is fully loaded, now hide the loading screen
// This will trigger OnInitialLoadingComplete via the event when animation completes
initialLoadingScreen.HideLoadingScreen();
// Step 3: The OnInitialLoadingComplete method will handle playing the intro cinematic
// Step 4: StartingScene will be unloaded after the cinematic completes in OnIntroCinematicFinished
}
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();
initialLoadingScreen.HideLoadingScreen();
}
}
/// <summary>
/// Unloads the StartingScene, completing the transition to the main menu
/// </summary>
private async void UnloadStartingScene()
{
try
{
// Get the current scene (StartingScene)
Scene currentScene = SceneManager.GetActiveScene();
string startingSceneName = currentScene.name;
Debug.Log($"[BootSceneController] Unloading StartingScene: {startingSceneName}");
// Unload the StartingScene
await SceneManager.UnloadSceneAsync(startingSceneName);
// Set the main menu scene as the active scene
Scene mainMenuScene = SceneManager.GetSceneByName(mainMenuSceneName);
SceneManager.SetActiveScene(mainMenuScene);
Debug.Log($"[BootSceneController] Transition complete: {startingSceneName} unloaded, {mainMenuSceneName} is now active");
// Destroy the boot scene controller since its job is done
Destroy(gameObject);
}
catch (Exception e)
{
Logging.Warning($"[BootSceneController] Error unloading StartingScene: {e.Message}");
}
}
/// <summary>
/// Helper class to handle progress reporting without running into explicit interface implementation issues
/// </summary>
private class ProgressHandler
{
private Action<float> _progressAction;
public ProgressHandler(Action<float> progressAction)
{
_progressAction = progressAction;
}
public void ReportProgress(float value)
{
_progressAction?.Invoke(value);
}
}
}