176 lines
5.6 KiB
C#
176 lines
5.6 KiB
C#
using System;
|
|
using System.Collections;
|
|
using UnityEngine;
|
|
using UnityEngine.AddressableAssets;
|
|
using UnityEngine.ResourceManagement.AsyncOperations;
|
|
|
|
/// <summary>
|
|
/// Download sob demanda para os recursos configurados em Assets/Jogos.
|
|
/// Compatível com Unity 2019.3 e Addressables 1.1.10.
|
|
/// </summary>
|
|
public static class JogosAddressableDownloader
|
|
{
|
|
public static string GetLabelFromTag(string tagGame)
|
|
{
|
|
if (string.IsNullOrEmpty(tagGame))
|
|
return string.Empty;
|
|
|
|
string normalized = tagGame.Replace("\\", "/").Trim('/');
|
|
string[] parts = normalized.Split('/');
|
|
string gameFolder = parts.Length > 0 ? parts[0] : normalized;
|
|
|
|
return "jogo_" + gameFolder.ToLowerInvariant();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifica se a label existe no catálogo.
|
|
/// </summary>
|
|
public static IEnumerator ValidateLabel(
|
|
string gameLabel,
|
|
Action<bool> onCompleted,
|
|
Action<string> onError = null)
|
|
{
|
|
if (string.IsNullOrEmpty(gameLabel))
|
|
{
|
|
if (onCompleted != null) onCompleted(false);
|
|
yield break;
|
|
}
|
|
|
|
AsyncOperationHandle<System.Collections.Generic.IList<UnityEngine.ResourceManagement.ResourceLocations.IResourceLocation>> handle =
|
|
Addressables.LoadResourceLocationsAsync(gameLabel);
|
|
|
|
yield return handle;
|
|
|
|
if (handle.Status == AsyncOperationStatus.Succeeded)
|
|
{
|
|
bool exists = handle.Result != null && handle.Result.Count > 0;
|
|
if (onCompleted != null) onCompleted(exists);
|
|
}
|
|
else
|
|
{
|
|
string error = "Erro ao validar a label Addressable: " + gameLabel;
|
|
Debug.LogError(error);
|
|
if (onError != null) onError(error);
|
|
if (onCompleted != null) onCompleted(false);
|
|
}
|
|
|
|
Addressables.Release(handle);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Baixa a label apenas se ela existir. Se não existir, continua sem erro.
|
|
/// Isso permite jogos que não possuem uma pasta correspondente em Assets/Jogos.
|
|
/// </summary>
|
|
public static IEnumerator DownloadGameIfExists(
|
|
string tagGame,
|
|
Action<float> onProgress = null,
|
|
Action<string> onStatus = null,
|
|
Action onSuccess = null,
|
|
Action<string> onError = null)
|
|
{
|
|
string gameLabel = GetLabelFromTag(tagGame);
|
|
bool labelExists = false;
|
|
|
|
yield return ValidateLabel(
|
|
gameLabel,
|
|
delegate(bool exists) { labelExists = exists; },
|
|
onError
|
|
);
|
|
|
|
if (!labelExists)
|
|
{
|
|
Debug.Log("Nenhum conteúdo adicional em Assets/Jogos para a label: " + gameLabel);
|
|
if (onProgress != null) onProgress(1f);
|
|
if (onStatus != null) onStatus("Sem conteúdo adicional para baixar.");
|
|
if (onSuccess != null) onSuccess();
|
|
yield break;
|
|
}
|
|
|
|
yield return DownloadGame(gameLabel, onProgress, onStatus, onSuccess, onError);
|
|
}
|
|
|
|
public static IEnumerator DownloadGame(
|
|
string gameLabel,
|
|
Action<float> onProgress = null,
|
|
Action<string> onStatus = null,
|
|
Action onSuccess = null,
|
|
Action<string> onError = null)
|
|
{
|
|
if (string.IsNullOrEmpty(gameLabel))
|
|
{
|
|
string error = "A label do jogo está vazia.";
|
|
Debug.LogError(error);
|
|
if (onError != null) onError(error);
|
|
yield break;
|
|
}
|
|
|
|
if (onStatus != null) onStatus("Verificando conteúdo adicional...");
|
|
|
|
AsyncOperationHandle<long> sizeHandle =
|
|
Addressables.GetDownloadSizeAsync(gameLabel);
|
|
|
|
yield return sizeHandle;
|
|
|
|
if (sizeHandle.Status != AsyncOperationStatus.Succeeded)
|
|
{
|
|
string error = "Não foi possível consultar o tamanho da label: " + gameLabel;
|
|
Debug.LogError(error);
|
|
if (onError != null) onError(error);
|
|
Addressables.Release(sizeHandle);
|
|
yield break;
|
|
}
|
|
|
|
long downloadSize = sizeHandle.Result;
|
|
Addressables.Release(sizeHandle);
|
|
|
|
if (downloadSize <= 0)
|
|
{
|
|
if (onProgress != null) onProgress(1f);
|
|
if (onStatus != null) onStatus("Conteúdo adicional já está no cache.");
|
|
if (onSuccess != null) onSuccess();
|
|
yield break;
|
|
}
|
|
|
|
if (onStatus != null)
|
|
onStatus("Baixando recursos do jogo: " + FormatBytes(downloadSize));
|
|
|
|
AsyncOperationHandle downloadHandle =
|
|
Addressables.DownloadDependenciesAsync(gameLabel);
|
|
|
|
while (!downloadHandle.IsDone)
|
|
{
|
|
if (onProgress != null)
|
|
onProgress(downloadHandle.PercentComplete);
|
|
|
|
yield return null;
|
|
}
|
|
|
|
if (downloadHandle.Status == AsyncOperationStatus.Succeeded)
|
|
{
|
|
if (onProgress != null) onProgress(1f);
|
|
if (onStatus != null) onStatus("Recursos adicionais baixados.");
|
|
if (onSuccess != null) onSuccess();
|
|
}
|
|
else
|
|
{
|
|
string error = "Erro ao baixar a label: " + gameLabel;
|
|
Debug.LogError(error);
|
|
if (onError != null) onError(error);
|
|
}
|
|
|
|
Addressables.Release(downloadHandle);
|
|
}
|
|
|
|
public static string FormatBytes(long bytes)
|
|
{
|
|
const long kb = 1024L;
|
|
const long mb = kb * 1024L;
|
|
const long gb = mb * 1024L;
|
|
|
|
if (bytes >= gb) return (bytes / (float)gb).ToString("0.00") + " GB";
|
|
if (bytes >= mb) return (bytes / (float)mb).ToString("0.00") + " MB";
|
|
if (bytes >= kb) return (bytes / (float)kb).ToString("0.00") + " KB";
|
|
return bytes + " bytes";
|
|
}
|
|
}
|