using System; using System.Collections; using UnityEngine; using UnityEngine.UI; using TMPro; using UnityEngine.SceneManagement; namespace CustomAssetBundleSystem { /// /// Manages AssetBundle downloads during LoadingScreen with UI feedback /// Checks cache, downloads if needed, handles offline mode /// public class AssetBundleDownloadManager : MonoBehaviour { [Header("UI References")] [SerializeField] private Slider loadingSlider; [SerializeField] private TextMeshProUGUI loadingText; [SerializeField] private TextMeshProUGUI hintsText; [SerializeField] private GameObject noInternetPanel; // Optional: Shows when internet required but not available [Header("Download Settings")] [SerializeField] private string[] bundlesToPreload = new[] { "gamescene" }; [SerializeField] private float minDisplayTime = 2f; // Minimum time to show loading (for UX) [Header("Hints")] [SerializeField] private string[] downloadHints = new[] { "Downloading game content...", "Preparing assets for better performance...", "First time setup - this only happens once!", "Future launches will be instant!" }; [SerializeField] private string[] cachedHints = new[] { "Complete Weekly Missions to gain XP", "Complete a 20 Wins streak to level up in Rank", "Missions change every Week" }; // State private bool _isDownloading = false; private bool _downloadComplete = false; private bool _hasInternet = true; private RemoteAssetBundleManager _bundleManager; // Events public event Action OnDownloadComplete; // true = success, false = failed private void Awake() { _bundleManager = RemoteAssetBundleManager.Instance; } /// /// Start the download process - call this from LoadingScreen /// public IEnumerator StartDownloadProcess(Action onComplete = null) { if (_isDownloading) { Debug.LogWarning("[DownloadManager] Download already in progress"); yield break; } _isDownloading = true; _downloadComplete = false; float startTime = Time.time; Debug.Log("[DownloadManager] Starting AssetBundle download process..."); // Step 1: Initialize RemoteAssetBundleManager (downloads catalog) yield return InitializeBundleSystem(); if (!_bundleManager.IsInitialized) { Debug.LogError("[DownloadManager] Failed to initialize bundle system"); HandleDownloadFailed("Failed to connect to server"); onComplete?.Invoke(false); OnDownloadComplete?.Invoke(false); yield break; } // Step 2: Check if bundles are already cached bool allCached = CheckIfBundlesCached(); if (allCached) { Debug.Log("[DownloadManager] ✓ All bundles already cached! (Offline play available)"); UpdateUI(1f, "Ready!", cachedHints); // Show success for minimum display time float elapsed = Time.time - startTime; if (elapsed < minDisplayTime) { yield return new WaitForSeconds(minDisplayTime - elapsed); } _downloadComplete = true; _isDownloading = false; onComplete?.Invoke(true); OnDownloadComplete?.Invoke(true); yield break; } // Step 3: Need to download - check internet connectivity _hasInternet = Application.internetReachability != NetworkReachability.NotReachable; if (!_hasInternet) { Debug.LogWarning("[DownloadManager] No internet connection and bundles not cached"); HandleNoInternet(); onComplete?.Invoke(false); OnDownloadComplete?.Invoke(false); yield break; } // Step 4: Download bundles with progress updates Debug.Log($"[DownloadManager] Downloading {bundlesToPreload.Length} bundle(s)..."); UpdateUI(0f, "Downloading game content", downloadHints); bool downloadSuccess = true; int bundleIndex = 0; foreach (string bundleName in bundlesToPreload) { bundleIndex++; Debug.Log($"[DownloadManager] Downloading bundle {bundleIndex}/{bundlesToPreload.Length}: {bundleName}"); bool bundleLoaded = false; float bundleProgress = 0f; // Subscribe to progress updates void ProgressHandler(string name, float progress) { if (name == bundleName) { bundleProgress = progress; float overallProgress = (bundleIndex - 1f + progress) / bundlesToPreload.Length; UpdateUI(overallProgress, $"Downloading {bundleName}", downloadHints); } } _bundleManager.OnBundleDownloadProgress += ProgressHandler; // Start download yield return _bundleManager.LoadBundleAsync(bundleName, (bundle) => { bundleLoaded = (bundle != null); }); _bundleManager.OnBundleDownloadProgress -= ProgressHandler; if (!bundleLoaded) { Debug.LogError($"[DownloadManager] Failed to download bundle: {bundleName}"); downloadSuccess = false; break; } Debug.Log($"[DownloadManager] ✓ Bundle '{bundleName}' ready!"); } if (!downloadSuccess) { HandleDownloadFailed("Failed to download game content"); onComplete?.Invoke(false); OnDownloadComplete?.Invoke(false); yield break; } // Step 5: Success! UpdateUI(1f, "Download complete!", downloadHints); Debug.Log("[DownloadManager] ✓ All bundles downloaded and cached successfully!"); // Show success for minimum display time float totalElapsed = Time.time - startTime; if (totalElapsed < minDisplayTime) { yield return new WaitForSeconds(minDisplayTime - totalElapsed); } _downloadComplete = true; _isDownloading = false; onComplete?.Invoke(true); OnDownloadComplete?.Invoke(true); } /// /// Initialize the bundle system (downloads catalog) /// private IEnumerator InitializeBundleSystem() { Debug.Log("[DownloadManager] Initializing bundle system..."); UpdateUI(0.05f, "Connecting to server", downloadHints); yield return _bundleManager.InitializeAsync(); if (_bundleManager.IsInitialized) { Debug.Log("[DownloadManager] ✓ Bundle system initialized"); } } /// /// Check if all required bundles are already cached /// private bool CheckIfBundlesCached() { foreach (string bundleName in bundlesToPreload) { if (!_bundleManager.IsBundleCached(bundleName)) { Debug.Log($"[DownloadManager] Bundle '{bundleName}' not cached - download required"); return false; } } return true; } /// /// Update UI elements with progress and hints /// private void UpdateUI(float progress, string statusText, string[] hints) { if (loadingSlider != null) { loadingSlider.value = progress; } if (loadingText != null) { loadingText.text = statusText; } if (hintsText != null && hints != null && hints.Length > 0) { // Show random hint or cycle through them int hintIndex = Mathf.FloorToInt(progress * hints.Length); hintIndex = Mathf.Clamp(hintIndex, 0, hints.Length - 1); hintsText.text = hints[hintIndex]; } } /// /// Handle no internet connection scenario /// private void HandleNoInternet() { Debug.LogWarning("[DownloadManager] ⚠️ No internet connection!"); if (loadingText != null) { loadingText.text = "No Internet Connection"; } if (hintsText != null) { hintsText.text = "Please connect to the internet to download game content"; } if (noInternetPanel != null) { noInternetPanel.SetActive(true); } // Don't proceed - block user until they have internet _isDownloading = false; } /// /// Handle download failure /// private void HandleDownloadFailed(string errorMessage) { Debug.LogError($"[DownloadManager] Download failed: {errorMessage}"); if (loadingText != null) { loadingText.text = "Download Failed"; } if (hintsText != null) { hintsText.text = errorMessage; } _isDownloading = false; } /// /// Check if download is complete and successful /// public bool IsDownloadComplete() { return _downloadComplete; } /// /// Retry button handler (for no internet panel) /// public void RetryDownload() { if (noInternetPanel != null) { noInternetPanel.SetActive(false); } // Restart the download process StartCoroutine(StartDownloadProcess()); } /// /// Get cache status for UI display /// public string GetCacheStatus() { if (!_bundleManager.IsInitialized) { return "Not initialized"; } int cachedCount = 0; foreach (string bundleName in bundlesToPreload) { if (_bundleManager.IsBundleCached(bundleName)) { cachedCount++; } } if (cachedCount == bundlesToPreload.Length) { return "All content cached (Offline play available)"; } else if (cachedCount > 0) { return $"{cachedCount}/{bundlesToPreload.Length} bundles cached"; } else { return "Download required"; } } } }