Merge branch 'main' into DamianBranch

This commit is contained in:
2025-10-14 11:29:29 +00:00
26 changed files with 1742 additions and 254 deletions

View File

@@ -1,4 +1,5 @@
using System.Collections;
using System;
using UnityEngine;
using UnityEngine.UI;
using Core;
@@ -22,9 +23,52 @@ namespace UI
private Coroutine _progressCoroutine;
private bool _loadingComplete = false;
private bool _animationComplete = false;
private Action _onLoadingScreenFullyHidden;
private static LoadingScreenController _instance;
private static bool _isQuitting;
/// <summary>
/// Delegate for providing progress values from different sources
/// </summary>
public delegate float ProgressProvider();
/// <summary>
/// Current progress provider being used for the loading screen
/// </summary>
private ProgressProvider _currentProgressProvider;
/// <summary>
/// Default progress provider that returns 0 (or 1 if loading is complete)
/// </summary>
private float DefaultProgressProvider() => _loadingComplete ? 1f : 0f;
/// <summary>
/// Check if the loading screen is currently active
/// </summary>
public bool IsActive => loadingScreenContainer != null && loadingScreenContainer.activeSelf;
public static LoadingScreenController Instance
{
get
{
if (_instance == null && Application.isPlaying && !_isQuitting)
{
_instance = FindAnyObjectByType<LoadingScreenController>();
if (_instance == null)
{
var go = new GameObject("LoadingScreenController");
_instance = go.AddComponent<LoadingScreenController>();
}
}
return _instance;
}
}
private void Awake()
{
_instance = this;
if (loadingScreenContainer == null)
loadingScreenContainer = gameObject;
@@ -38,8 +82,16 @@ namespace UI
/// <summary>
/// Shows the loading screen and resets the progress bar to zero
/// </summary>
public void ShowLoadingScreen()
/// <param name="progressProvider">Optional delegate to provide progress values (0-1). If null, uses default provider.</param>
/// <param name="onComplete">Optional callback when loading screen is fully hidden</param>
public void ShowLoadingScreen(ProgressProvider progressProvider = null, Action onComplete = null)
{
// Store the completion callback
_onLoadingScreenFullyHidden = onComplete;
// Set the progress provider, use default if none provided
_currentProgressProvider = progressProvider ?? DefaultProgressProvider;
// Stop any existing progress coroutine
if (_progressCoroutine != null)
{
@@ -67,7 +119,7 @@ namespace UI
/// <summary>
/// Animates the progress bar at a steady pace over the minimum display time,
/// while also checking actual loading progress from SceneManagerService
/// while also checking actual loading progress from the current progress provider
/// </summary>
private IEnumerator AnimateProgressBar()
{
@@ -80,12 +132,8 @@ namespace UI
float elapsedTime = Time.time - startTime;
float steadyProgress = Mathf.Clamp01(elapsedTime / minimumDisplayTime);
// Get the actual loading progress from SceneManagerService
float actualProgress = 0f;
if (SceneManagerService.Instance != null)
{
actualProgress = SceneManagerService.Instance.GetAggregateLoadProgress();
}
// Get the actual loading progress from the current provider
float actualProgress = _currentProgressProvider();
// If loading is complete, actualProgress should be 1.0
if (_loadingComplete)
@@ -133,6 +181,10 @@ namespace UI
{
loadingScreenContainer.SetActive(false);
Debug.Log("[LoadingScreen] Animation AND loading complete, hiding screen");
// Invoke the callback when fully hidden
_onLoadingScreenFullyHidden?.Invoke();
_onLoadingScreenFullyHidden = null;
}
}
@@ -156,6 +208,10 @@ namespace UI
{
loadingScreenContainer.SetActive(false);
Debug.Log("[LoadingScreen] Animation already complete, hiding screen immediately");
// Invoke the callback when fully hidden
_onLoadingScreenFullyHidden?.Invoke();
_onLoadingScreenFullyHidden = null;
}
}
else
@@ -164,5 +220,35 @@ namespace UI
// The coroutine will handle hiding when animation completes
}
}
/// <summary>
/// Waits until the loading screen is fully hidden before continuing
/// </summary>
/// <returns>Task that completes when the loading screen is hidden</returns>
public System.Threading.Tasks.Task WaitForLoadingScreenToHideAsync()
{
var tcs = new System.Threading.Tasks.TaskCompletionSource<bool>();
// If the loading screen is not active, complete immediately
if (!IsActive)
{
tcs.SetResult(true);
return tcs.Task;
}
// Store existing callback to chain it
Action existingCallback = _onLoadingScreenFullyHidden;
// Set new callback
_onLoadingScreenFullyHidden = () => {
// Call existing callback if any
existingCallback?.Invoke();
// Complete the task
tcs.SetResult(true);
};
return tcs.Task;
}
}
}

View File

@@ -48,10 +48,10 @@ namespace UI
// Subscribe to scene loaded events
SceneManagerService.Instance.SceneLoadCompleted += SetPauseMenuByLevel;
#if UNITY_EDITOR
// Set initial state based on current scene
SetPauseMenuByLevel(SceneManager.GetActiveScene().name);
#if UNITY_EDITOR
// Initialize pause menu state
HidePauseMenu(false);
#endif