Files
DeviantMobile-Rohan/Assets/Scripts/AssetBundleSystem/AssetBundleDownloadManager.cs

348 lines
11 KiB
C#

using System;
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using UnityEngine.SceneManagement;
namespace CustomAssetBundleSystem
{
/// <summary>
/// Manages AssetBundle downloads during LoadingScreen with UI feedback
/// Checks cache, downloads if needed, handles offline mode
/// </summary>
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<bool> OnDownloadComplete; // true = success, false = failed
private void Awake()
{
_bundleManager = RemoteAssetBundleManager.Instance;
}
/// <summary>
/// Start the download process - call this from LoadingScreen
/// </summary>
public IEnumerator StartDownloadProcess(Action<bool> 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);
}
/// <summary>
/// Initialize the bundle system (downloads catalog)
/// </summary>
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");
}
}
/// <summary>
/// Check if all required bundles are already cached
/// </summary>
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;
}
/// <summary>
/// Update UI elements with progress and hints
/// </summary>
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];
}
}
/// <summary>
/// Handle no internet connection scenario
/// </summary>
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;
}
/// <summary>
/// Handle download failure
/// </summary>
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;
}
/// <summary>
/// Check if download is complete and successful
/// </summary>
public bool IsDownloadComplete()
{
return _downloadComplete;
}
/// <summary>
/// Retry button handler (for no internet panel)
/// </summary>
public void RetryDownload()
{
if (noInternetPanel != null)
{
noInternetPanel.SetActive(false);
}
// Restart the download process
StartCoroutine(StartDownloadProcess());
}
/// <summary>
/// Get cache status for UI display
/// </summary>
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";
}
}
}
}