using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.ResourceManagement.ResourceProviders; using UnityEngine.SceneManagement; using UnityEngine.UI; using TMPro; using System.Collections; public class HeavyScenePreloader : MonoBehaviour { [Header("Adresse de la scène Addressable")] public string sceneAddress = "heavy_scene"; [Header("UI (facultatif)")] public Slider progressBar; // Barre de progression public TextMeshProUGUI progressText; // Texte en dessous de la barre public TextMeshProUGUI loadingLabel; // Texte au-dessus de la barre ("Chargement...") private AsyncOperationHandle loadHandle; private float lastProgress = 0f; private float lastTime; void Start() { // Lancer le chargement en tâche de fond dès le lancement PreloadSceneInBackground(); } /// /// Étape 1 : Précharge la scène Addressable sans l’activer /// public void PreloadSceneInBackground() { Debug.Log("Début du chargement de la scène mesh en tâche de fond..."); loadHandle = Addressables.LoadSceneAsync(sceneAddress, LoadSceneMode.Additive, activateOnLoad: false); loadHandle.Completed += OnScenePreloaded; // Initialisation du temps lastTime = Time.time; // Lancer le suivi de progression StartCoroutine(MonitorLoadingProgress()); } /// /// Appelée une fois la scène chargée (mais pas encore activée) /// private void OnScenePreloaded(AsyncOperationHandle handle) { if (handle.Status == AsyncOperationStatus.Succeeded) { Debug.Log("Scène préchargée, activation automatique..."); handle.Result.ActivateAsync(); // Activation immédiate } else { Debug.LogError("Erreur lors du chargement de la scène."); } } /// /// Suivi de la progression du chargement (WebGL friendly) /// private IEnumerator MonitorLoadingProgress() { while (!loadHandle.IsDone) { float progress = GetLoadingProgress(); // float deltaTime = Time.time - lastTime; // float deltaProgress = progress - lastProgress; // lastProgress = progress; // lastTime = Time.time; // Estimation taux de transfert (fictif basé sur %) // float estimatedBytes = 100f * 1024f * 1024f * 1.05f; // suppose 100 Mo max (à adapter) // float speedBps = (deltaProgress * estimatedBytes ) / deltaTime; // string speedText; // if (float.IsNaN(speedBps) || float.IsInfinity(speedBps)) // { // speedText = " -- "; // } // else // { // speedText = speedBps > 1024f * 1024f // ? $"{(speedBps / (1024f * 1024f)):0.0} Mo/s" // : $"{(speedBps / 1024f):0.0} Ko/s"; // } Debug.Log($"Chargement mesh : {Mathf.RoundToInt(progress * 100)}%"); if (progressBar != null) { progressBar.value = progress; } if (progressText != null) { progressText.text = $"{Mathf.RoundToInt(progress * 105)}%"; } if (loadingLabel != null) { loadingLabel.text = "Chargement du modèle en cours..."; } yield return null; } if (progressBar != null) { progressBar.value = 1f; progressBar.gameObject.SetActive(false); } if (progressText != null) { progressText.gameObject.SetActive(false); } if (loadingLabel != null) { loadingLabel.gameObject.SetActive(false); } } /// /// Fonction publique pour obtenir la progression actuelle du chargement (0 à 1) /// public float GetLoadingProgress() { if (loadHandle.IsValid()) { return loadHandle.PercentComplete; } else { return 0f; } } }