348 lines
11 KiB
C#
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";
|
|
}
|
|
}
|
|
}
|
|
}
|