using System.Collections; using UnityEngine; using UnityEngine.UI; using Core; namespace UI { /// /// Controls the loading screen UI display, progress updates, and timing /// 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); } } /// /// Shows the loading screen and resets the progress bar to zero /// 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()); } /// /// Animates the progress bar at a steady pace over the minimum display time, /// while also checking actual loading progress from SceneManagerService /// 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; } /// /// Called when the actual loading process is complete /// 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 } } } }