232 lines
7.4 KiB
C#
232 lines
7.4 KiB
C#
using System;
|
||
using System.Collections;
|
||
using System.Threading.Tasks;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
using TcgEngine.UI;
|
||
|
||
namespace TcgEngine
|
||
{
|
||
/// <summary>
|
||
/// 资源初始化
|
||
/// </summary>
|
||
public class ResourceInitializer : MonoBehaviour
|
||
{
|
||
[Header("UI References")]
|
||
public GameObject downloadPanel;
|
||
public Text statusText;
|
||
public Slider progressBar;
|
||
public Button retryButton;
|
||
public Button skipButton;
|
||
|
||
[Header("Settings")]
|
||
public bool allowSkip = false;
|
||
public float timeoutSeconds = 30f;
|
||
|
||
private bool downloadCompleted = false;
|
||
private bool downloadFailed = false;
|
||
|
||
public event Action OnInitializationComplete;
|
||
public event Action<string> OnInitializationFailed;
|
||
|
||
private void Start()
|
||
{
|
||
if (downloadPanel != null)
|
||
downloadPanel.SetActive(false);
|
||
|
||
if (retryButton != null)
|
||
{
|
||
// TODO 重试
|
||
retryButton.gameObject.SetActive(false);
|
||
}
|
||
|
||
if (skipButton != null)
|
||
{
|
||
// TODO 跳过
|
||
skipButton.gameObject.SetActive(false);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 开始资源初始化流程
|
||
/// </summary>
|
||
public async Task<bool> InitializeResources()
|
||
{
|
||
try
|
||
{
|
||
UpdateStatus("正在检查资源版本...");
|
||
|
||
// 获取或创建ResourceDownloader实例
|
||
ResourceDownloader downloader = ResourceDownloader.Get();
|
||
|
||
// 订阅下载事件
|
||
SubscribeToDownloadEvents(downloader);
|
||
|
||
// 检查是否需要更新
|
||
bool needsUpdate = await downloader.CheckForUpdates();
|
||
|
||
if (!needsUpdate)
|
||
{
|
||
UpdateStatus("资源已是最新版本");
|
||
CompleteInitialization();
|
||
return true;
|
||
}
|
||
|
||
UpdateStatus("发现新版本,正在下载资源...");
|
||
UpdateProgress(0f);
|
||
|
||
// 开始下载和更新
|
||
bool success = await DownloadWithTimeout(downloader);
|
||
|
||
if (success)
|
||
{
|
||
UpdateStatus("资源更新完成!");
|
||
UpdateProgress(1f);
|
||
await Task.Delay(1000);
|
||
CompleteInitialization();
|
||
return true;
|
||
}
|
||
else
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Debug.LogError($"Resource initialization failed: {e.Message}");
|
||
UpdateStatus($"初始化失败: {e.Message}");
|
||
return false;
|
||
}
|
||
finally
|
||
{
|
||
// 取消订阅事件
|
||
if (ResourceDownloader.Get() != null)
|
||
{
|
||
UnsubscribeFromDownloadEvents(ResourceDownloader.Get());
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 带超时的下载
|
||
/// </summary>
|
||
private async Task<bool> DownloadWithTimeout(ResourceDownloader downloader)
|
||
{
|
||
var downloadTask = downloader.DownloadAndUpdateResources();
|
||
var timeoutTask = Task.Delay(TimeSpan.FromSeconds(timeoutSeconds));
|
||
|
||
var completedTask = await Task.WhenAny(downloadTask, timeoutTask);
|
||
|
||
if (completedTask == timeoutTask)
|
||
{
|
||
UpdateStatus("下载超时");
|
||
OnInitializationFailed?.Invoke("Download timeout");
|
||
return false;
|
||
}
|
||
|
||
return await downloadTask;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 订阅下载事件
|
||
/// </summary>
|
||
private void SubscribeToDownloadEvents(ResourceDownloader downloader)
|
||
{
|
||
downloader.OnDownloadProgress += OnDownloadProgress;
|
||
downloader.OnDownloadComplete += OnDownloadComplete;
|
||
downloader.OnDownloadError += OnDownloadError;
|
||
downloader.OnExtractProgress += OnExtractProgress;
|
||
downloader.OnExtractComplete += OnExtractComplete;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 取消订阅下载事件
|
||
/// </summary>
|
||
private void UnsubscribeFromDownloadEvents(ResourceDownloader downloader)
|
||
{
|
||
downloader.OnDownloadProgress -= OnDownloadProgress;
|
||
downloader.OnDownloadComplete -= OnDownloadComplete;
|
||
downloader.OnDownloadError -= OnDownloadError;
|
||
downloader.OnExtractProgress -= OnExtractProgress;
|
||
downloader.OnExtractComplete -= OnExtractComplete;
|
||
}
|
||
|
||
private void OnDownloadProgress(float progress)
|
||
{
|
||
UpdateProgress(progress * 0.7f);
|
||
UpdateStatus($"正在下载资源... {(progress * 100):F1}%");
|
||
}
|
||
|
||
private void OnDownloadComplete(string filePath)
|
||
{
|
||
UpdateProgress(0.7f);
|
||
UpdateStatus("下载完成,正在解压...");
|
||
}
|
||
|
||
private void OnDownloadError(string error)
|
||
{
|
||
downloadFailed = true;
|
||
UpdateStatus($"下载失败: {error}");
|
||
OnInitializationFailed?.Invoke(error);
|
||
}
|
||
|
||
private void OnExtractProgress(float progress)
|
||
{
|
||
UpdateProgress(0.7f + progress * 0.3f);
|
||
UpdateStatus($"正在解压资源... {(progress * 100):F1}%");
|
||
}
|
||
|
||
private void OnExtractComplete()
|
||
{
|
||
downloadCompleted = true;
|
||
UpdateProgress(1f);
|
||
UpdateStatus("资源解压完成!");
|
||
|
||
// 打印解压后的文件夹位置
|
||
if (ResourceDownloader.Get() != null)
|
||
{
|
||
ResourceDownloader.Get().LogResourcePaths();
|
||
|
||
// 另外也可以直接打印路径
|
||
string spritesPath = ResourceDownloader.Get().GetSpritesDirectoryPath();
|
||
Debug.Log($"[ResourceInitializer] 资源解压到: {spritesPath}");
|
||
|
||
// 在macOS上,可以直接用这个命令在终端中打开文件夹
|
||
Debug.Log($"[ResourceInitializer] 打开文件夹命令: open \"{spritesPath}\"");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新状态文本
|
||
/// </summary>
|
||
private void UpdateStatus(string status)
|
||
{
|
||
if (statusText != null)
|
||
{
|
||
statusText.text = status;
|
||
}
|
||
Debug.Log($"[ResourceInitializer] {status}");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新进度条
|
||
/// </summary>
|
||
private void UpdateProgress(float progress)
|
||
{
|
||
if (progressBar != null)
|
||
{
|
||
progressBar.value = Mathf.Clamp01(progress);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 完成初始化
|
||
/// </summary>
|
||
private void CompleteInitialization()
|
||
{
|
||
downloadCompleted = true;
|
||
OnInitializationComplete?.Invoke();
|
||
}
|
||
}
|
||
}
|