169 lines
6.2 KiB
C#
169 lines
6.2 KiB
C#
using System.Collections;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using Core;
|
|
|
|
namespace UI
|
|
{
|
|
/// <summary>
|
|
/// Controls the loading screen UI display, progress updates, and timing
|
|
/// </summary>
|
|
public class LoadingScreenController : MonoBehaviour
|
|
{
|
|
[Header("UI References")]
|
|
[SerializeField] private GameObject loadingScreenContainer;
|
|
[SerializeField] private Image progressBarImage;
|
|
|
|
[Header("Settings")]
|
|
[SerializeField] private float minimumDisplayTime = 1.0f;
|
|
[SerializeField] private float progressUpdateInterval = 0.1f;
|
|
|
|
private float _displayStartTime;
|
|
private Coroutine _progressCoroutine;
|
|
private bool _loadingComplete = false;
|
|
private bool _animationComplete = false;
|
|
|
|
private void Awake()
|
|
{
|
|
if (loadingScreenContainer == null)
|
|
loadingScreenContainer = gameObject;
|
|
|
|
// Ensure the loading screen is initially hidden
|
|
if (loadingScreenContainer != null)
|
|
{
|
|
loadingScreenContainer.SetActive(false);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Shows the loading screen and resets the progress bar to zero
|
|
/// </summary>
|
|
public void ShowLoadingScreen()
|
|
{
|
|
// Stop any existing progress coroutine
|
|
if (_progressCoroutine != null)
|
|
{
|
|
StopCoroutine(_progressCoroutine);
|
|
_progressCoroutine = null;
|
|
}
|
|
|
|
_displayStartTime = Time.time;
|
|
_loadingComplete = false;
|
|
_animationComplete = false;
|
|
|
|
if (progressBarImage != null)
|
|
{
|
|
progressBarImage.fillAmount = 0f;
|
|
}
|
|
|
|
if (loadingScreenContainer != null)
|
|
{
|
|
loadingScreenContainer.SetActive(true);
|
|
}
|
|
|
|
// Start the progress filling coroutine
|
|
_progressCoroutine = StartCoroutine(AnimateProgressBar());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Animates the progress bar at a steady pace over the minimum display time,
|
|
/// while also checking actual loading progress from SceneManagerService
|
|
/// </summary>
|
|
private IEnumerator AnimateProgressBar()
|
|
{
|
|
float startTime = Time.time;
|
|
|
|
// Continue until both animation and loading are complete
|
|
while (!_animationComplete)
|
|
{
|
|
// Calculate the steady progress based on elapsed time
|
|
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();
|
|
}
|
|
|
|
// If loading is complete, actualProgress should be 1.0
|
|
if (_loadingComplete)
|
|
{
|
|
actualProgress = 1.0f;
|
|
}
|
|
|
|
// Use the minimum of steady progress and actual progress
|
|
// This ensures we don't show more progress than actual loading
|
|
float displayProgress = Mathf.Min(steadyProgress, actualProgress);
|
|
|
|
// Log the progress values for debugging
|
|
Debug.Log($"[LoadingScreen] Progress - Default: {steadyProgress:F2}, Actual: {actualProgress:F2}, Display: {displayProgress:F2}");
|
|
|
|
// Directly set the progress bar fill amount without smoothing
|
|
if (progressBarImage != null)
|
|
{
|
|
progressBarImage.fillAmount = displayProgress;
|
|
}
|
|
|
|
// Check if the animation has completed
|
|
// Animation is complete when we've reached the minimum display time AND we're at 100% progress
|
|
if (steadyProgress >= 1.0f && displayProgress >= 1.0f)
|
|
{
|
|
_animationComplete = true;
|
|
Debug.Log("[LoadingScreen] Animation complete");
|
|
break;
|
|
}
|
|
|
|
// Wait for the configured interval before updating again
|
|
yield return new WaitForSeconds(progressUpdateInterval);
|
|
}
|
|
|
|
// Ensure we end at 100% progress
|
|
if (progressBarImage != null)
|
|
{
|
|
progressBarImage.fillAmount = 1.0f;
|
|
Debug.Log("[LoadingScreen] Final progress set to 1.0");
|
|
}
|
|
|
|
// Hide the screen if loading is also complete
|
|
if (_loadingComplete)
|
|
{
|
|
if (loadingScreenContainer != null)
|
|
{
|
|
loadingScreenContainer.SetActive(false);
|
|
Debug.Log("[LoadingScreen] Animation AND loading complete, hiding screen");
|
|
}
|
|
}
|
|
|
|
_progressCoroutine = null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called when the actual loading process is complete
|
|
/// </summary>
|
|
public void HideLoadingScreen()
|
|
{
|
|
Debug.Log("[LoadingScreen] Loading complete, marking loading as finished");
|
|
|
|
// Mark that loading is complete
|
|
_loadingComplete = true;
|
|
|
|
// If animation is already complete, we can hide the screen now
|
|
if (_animationComplete)
|
|
{
|
|
if (loadingScreenContainer != null)
|
|
{
|
|
loadingScreenContainer.SetActive(false);
|
|
Debug.Log("[LoadingScreen] Animation already complete, hiding screen immediately");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Debug.Log("[LoadingScreen] Animation still in progress, waiting for it to complete");
|
|
// The coroutine will handle hiding when animation completes
|
|
}
|
|
}
|
|
}
|
|
}
|