Author a bootstrap scene first approach

This commit is contained in:
Michal Pikulski
2025-10-16 11:06:05 +02:00
parent 1ae065b45d
commit 1ee5519716
9 changed files with 630 additions and 130 deletions

View File

@@ -0,0 +1,127 @@
using System;
using UnityEngine;
using UI;
using Core;
using UnityEngine.SceneManagement;
namespace Bootstrap
{
/// <summary>
/// Controller for the boot scene that coordinates bootstrap initialization with loading screen
/// </summary>
public class BootSceneController : MonoBehaviour
{
[SerializeField] private string mainMenuSceneName = "MainMenu";
[SerializeField] private float minDelayAfterBoot = 0.5f; // Small delay after boot to ensure smooth transition
[SerializeField] private bool debugMode = false;
private bool _bootComplete = false;
private bool _hasStartedLoading = false;
private void Start()
{
Debug.Log("[BootSceneController] Boot scene started");
// Ensure the loading screen controller exists
if (LoadingScreenController.Instance == null)
{
Debug.LogError("[BootSceneController] No LoadingScreenController found in the scene!");
return;
}
// Show the loading screen immediately
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()
);
// Start the boot process if not already initialized
if (!CustomBoot.Initialised)
{
// Subscribe to the boot completion event
CustomBoot.OnBootCompleted += OnBootCompleted;
CustomBoot.OnBootProgressChanged += OnBootProgressChanged;
// Start initialization
CustomBoot.PerformInitialisation();
}
else
{
// If already initialized (can happen in editor testing), proceed immediately
Debug.Log("[BootSceneController] Bootstrap already initialized, proceeding to main menu");
OnBootCompleted();
}
// In debug mode, log additional information
if (debugMode)
{
InvokeRepeating(nameof(LogDebugInfo), 0.1f, 0.5f);
}
}
private void OnDestroy()
{
// Clean up event subscriptions
CustomBoot.OnBootCompleted -= OnBootCompleted;
CustomBoot.OnBootProgressChanged -= OnBootProgressChanged;
if (debugMode)
{
CancelInvoke(nameof(LogDebugInfo));
}
}
private void OnBootProgressChanged(float progress)
{
if (debugMode)
{
Debug.Log($"[BootSceneController] Boot progress: {progress:P0}");
}
}
private void LogDebugInfo()
{
Debug.Log($"[BootSceneController] Debug - Boot Progress: {CustomBoot.CurrentProgress:P0}, Boot Complete: {_bootComplete}, Loading Started: {_hasStartedLoading}");
}
private void OnBootCompleted()
{
// Unsubscribe to prevent duplicate calls
CustomBoot.OnBootCompleted -= OnBootCompleted;
Debug.Log("[BootSceneController] Boot process completed");
_bootComplete = true;
// After a small delay, tell the loading screen we're done
// This prevents jerky transitions if boot happens very quickly
Invoke(nameof(CompleteLoadingScreen), minDelayAfterBoot);
}
private void CompleteLoadingScreen()
{
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;
Debug.Log($"[BootSceneController] Loading main menu scene: {mainMenuSceneName}");
// Load the main menu scene
var progress = new Progress<float>(p => Debug.Log($"Loading main menu: {p * 100:F0}%"));
await SceneManagerService.Instance.SwitchSceneAsync(mainMenuSceneName, progress);
}
}
}