拉取资源
This commit is contained in:
@@ -59,7 +59,7 @@ namespace TcgEngine.UI
|
||||
{
|
||||
AvatarData avat = AvatarData.Get(user.avatar);
|
||||
if (avat != null)
|
||||
avatar.sprite = avat.avatar;
|
||||
avatar.sprite = avat.GetAvatar();
|
||||
}
|
||||
|
||||
if (online_img != null)
|
||||
|
||||
231
Assets/TcgEngine/Scripts/Menu/ResourceInitializer.cs
Normal file
231
Assets/TcgEngine/Scripts/Menu/ResourceInitializer.cs
Normal file
@@ -0,0 +1,231 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/TcgEngine/Scripts/Menu/ResourceInitializer.cs.meta
Normal file
11
Assets/TcgEngine/Scripts/Menu/ResourceInitializer.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4bd77c63e04004562a2ff98b99fcbc59
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
334
Assets/TcgEngine/Scripts/Menu/SplashScreenManager.cs
Normal file
334
Assets/TcgEngine/Scripts/Menu/SplashScreenManager.cs
Normal file
@@ -0,0 +1,334 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace TcgEngine.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// </summary>
|
||||
public class SplashScreenManager : MonoBehaviour
|
||||
{
|
||||
[Header("UI组件")]
|
||||
public Text statusText;
|
||||
public Slider progressBar;
|
||||
public Text progressText;
|
||||
public Image logoImage;
|
||||
public CanvasGroup mainCanvasGroup;
|
||||
|
||||
[Header("设置")]
|
||||
public string nextSceneName = "LoginMenu";
|
||||
public float fadeInDuration = 1f;
|
||||
public float fadeOutDuration = 1f;
|
||||
public float minimumDisplayTime = 3f;
|
||||
|
||||
[Header("音效")]
|
||||
public AudioClip splashMusic;
|
||||
|
||||
private float startTime;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
startTime = Time.time;
|
||||
InitializeUI();
|
||||
StartCoroutine(RunSplashSequence());
|
||||
}
|
||||
|
||||
private void InitializeUI()
|
||||
{
|
||||
// 设置初始状态
|
||||
if (mainCanvasGroup != null)
|
||||
mainCanvasGroup.alpha = 0f;
|
||||
|
||||
UpdateStatus("启动中...");
|
||||
UpdateProgress(0f);
|
||||
|
||||
// 播放音乐
|
||||
if (splashMusic != null)
|
||||
{
|
||||
AudioTool.Get().PlayMusic("splash", splashMusic, 0.6f);
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator RunSplashSequence()
|
||||
{
|
||||
// 淡入
|
||||
yield return StartCoroutine(FadeIn());
|
||||
|
||||
// 获取版本信息
|
||||
string version = GetCurrentVersion();
|
||||
// 显示版本信息
|
||||
UpdateStatus($"版本 {version}");
|
||||
UpdateProgress(0.1f);
|
||||
yield return new WaitForSeconds(0.5f);
|
||||
|
||||
// 开始资源初始化
|
||||
yield return StartCoroutine(InitializeResources());
|
||||
|
||||
// 确保最少显示时间
|
||||
yield return StartCoroutine(WaitForMinimumTime());
|
||||
|
||||
// 完成并跳转
|
||||
yield return StartCoroutine(CompleteAndTransition());
|
||||
}
|
||||
|
||||
private IEnumerator FadeIn()
|
||||
{
|
||||
if (mainCanvasGroup == null) yield break;
|
||||
|
||||
float elapsed = 0f;
|
||||
while (elapsed < fadeInDuration)
|
||||
{
|
||||
elapsed += Time.deltaTime;
|
||||
mainCanvasGroup.alpha = Mathf.Lerp(0f, 1f, elapsed / fadeInDuration);
|
||||
yield return null;
|
||||
}
|
||||
mainCanvasGroup.alpha = 1f;
|
||||
}
|
||||
|
||||
private IEnumerator InitializeResources()
|
||||
{
|
||||
UpdateStatus("正在初始化资源系统...");
|
||||
UpdateProgress(0.2f);
|
||||
yield return new WaitForSeconds(0.3f);
|
||||
|
||||
// 直接在主线程中调用ResourceDownloader
|
||||
ResourceDownloader downloader = null;
|
||||
|
||||
try
|
||||
{
|
||||
downloader = ResourceDownloader.Get();
|
||||
|
||||
// 订阅事件以获取进度更新
|
||||
downloader.OnDownloadProgress += OnDownloadProgress;
|
||||
downloader.OnExtractProgress += OnExtractProgress;
|
||||
downloader.OnDownloadComplete += OnDownloadComplete;
|
||||
downloader.OnExtractComplete += OnExtractComplete;
|
||||
downloader.OnDownloadError += OnDownloadError;
|
||||
|
||||
UpdateStatus("正在检查资源版本...");
|
||||
UpdateProgress(0.3f);
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.LogError($"[SplashScreenManager] 资源初始化异常: {e.Message}");
|
||||
UpdateStatus("资源初始化失败,使用现有资源");
|
||||
UpdateProgress(0.9f);
|
||||
yield break;
|
||||
}
|
||||
|
||||
// 使用协程包装异步调用
|
||||
yield return StartCoroutine(CheckAndDownloadResources(downloader));
|
||||
|
||||
// 取消订阅事件
|
||||
if (downloader != null)
|
||||
{
|
||||
downloader.OnDownloadProgress -= OnDownloadProgress;
|
||||
downloader.OnExtractProgress -= OnExtractProgress;
|
||||
downloader.OnDownloadComplete -= OnDownloadComplete;
|
||||
downloader.OnExtractComplete -= OnExtractComplete;
|
||||
downloader.OnDownloadError -= OnDownloadError;
|
||||
}
|
||||
|
||||
UpdateStatus("初始化完成!");
|
||||
UpdateProgress(1f);
|
||||
}
|
||||
|
||||
private IEnumerator CheckAndDownloadResources(ResourceDownloader downloader)
|
||||
{
|
||||
bool needsUpdate = false;
|
||||
bool taskCompleted = false;
|
||||
|
||||
// 异步检查更新
|
||||
downloader.CheckForUpdates().ContinueWith(task =>
|
||||
{
|
||||
needsUpdate = task.Result;
|
||||
taskCompleted = true;
|
||||
});
|
||||
|
||||
// 等待任务完成
|
||||
while (!taskCompleted)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
|
||||
if (!needsUpdate)
|
||||
{
|
||||
UpdateStatus("资源已是最新版本");
|
||||
UpdateProgress(0.9f);
|
||||
yield return new WaitForSeconds(0.5f);
|
||||
yield break;
|
||||
}
|
||||
|
||||
UpdateStatus("发现新版本,开始下载...");
|
||||
UpdateProgress(0.4f);
|
||||
|
||||
// 异步下载资源
|
||||
bool downloadSuccess = false;
|
||||
taskCompleted = false;
|
||||
|
||||
downloader.DownloadAndUpdateResources().ContinueWith(task =>
|
||||
{
|
||||
downloadSuccess = task.Result;
|
||||
taskCompleted = true;
|
||||
});
|
||||
|
||||
// 等待下载完成
|
||||
while (!taskCompleted)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
|
||||
if (downloadSuccess)
|
||||
{
|
||||
UpdateStatus("资源更新完成!");
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateStatus("下载失败,使用现有资源");
|
||||
}
|
||||
|
||||
UpdateProgress(0.95f);
|
||||
}
|
||||
|
||||
private void OnDownloadProgress(float progress)
|
||||
{
|
||||
float baseProgress = 0.4f;
|
||||
float range = 0.3f;
|
||||
UpdateProgress(baseProgress + progress * range);
|
||||
UpdateStatus($"正在下载资源 {(progress * 100):F0}%");
|
||||
}
|
||||
|
||||
private void OnDownloadComplete(string filePath)
|
||||
{
|
||||
UpdateStatus("下载完成,正在解压...");
|
||||
UpdateProgress(0.7f);
|
||||
}
|
||||
|
||||
private void OnDownloadError(string error)
|
||||
{
|
||||
UpdateStatus("下载出错,使用现有资源");
|
||||
Debug.LogWarning($"[SplashScreenManager] 下载错误: {error}");
|
||||
}
|
||||
|
||||
private void OnExtractProgress(float progress)
|
||||
{
|
||||
float baseProgress = 0.7f;
|
||||
float range = 0.2f;
|
||||
UpdateProgress(baseProgress + progress * range);
|
||||
UpdateStatus($"正在解压资源 {(progress * 100):F0}%");
|
||||
}
|
||||
|
||||
private void OnExtractComplete()
|
||||
{
|
||||
UpdateStatus("解压完成!");
|
||||
UpdateProgress(0.9f);
|
||||
}
|
||||
|
||||
private IEnumerator WaitForMinimumTime()
|
||||
{
|
||||
float elapsedTime = Time.time - startTime;
|
||||
float remainingTime = minimumDisplayTime - elapsedTime;
|
||||
|
||||
if (remainingTime > 0)
|
||||
{
|
||||
UpdateStatus("准备完成...");
|
||||
yield return new WaitForSeconds(remainingTime);
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator CompleteAndTransition()
|
||||
{
|
||||
UpdateStatus("准备进入游戏...");
|
||||
|
||||
// 淡出音乐
|
||||
if (splashMusic != null)
|
||||
{
|
||||
AudioTool.Get().FadeOutMusic("splash");
|
||||
}
|
||||
|
||||
// 淡出界面
|
||||
if (mainCanvasGroup != null)
|
||||
{
|
||||
float elapsed = 0f;
|
||||
while (elapsed < fadeOutDuration)
|
||||
{
|
||||
elapsed += Time.deltaTime;
|
||||
mainCanvasGroup.alpha = Mathf.Lerp(1f, 0f, elapsed / fadeOutDuration);
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
|
||||
// 显示黑屏并跳转
|
||||
var blackPanel = TcgEngine.UI.BlackPanel.Get();
|
||||
if (blackPanel != null)
|
||||
{
|
||||
blackPanel.Show();
|
||||
yield return new WaitForSeconds(0.3f);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("[SplashScreenManager] BlackPanel not found, skipping fade effect");
|
||||
yield return new WaitForSeconds(0.1f);
|
||||
}
|
||||
|
||||
// 跳转到下一个场景
|
||||
SceneManager.LoadScene(nextSceneName);
|
||||
}
|
||||
|
||||
private void UpdateStatus(string message)
|
||||
{
|
||||
if (statusText != null)
|
||||
statusText.text = message;
|
||||
Debug.Log($"[SplashScreen] {message}");
|
||||
}
|
||||
|
||||
private void UpdateProgress(float progress)
|
||||
{
|
||||
progress = Mathf.Clamp01(progress);
|
||||
|
||||
if (progressBar != null)
|
||||
progressBar.value = progress;
|
||||
|
||||
if (progressText != null)
|
||||
progressText.text = $"{(progress * 100):F0}%";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前版本信息
|
||||
/// </summary>
|
||||
private string GetCurrentVersion()
|
||||
{
|
||||
try
|
||||
{
|
||||
string versionFile = System.IO.Path.Combine(Application.persistentDataPath, "version.txt");
|
||||
if (System.IO.File.Exists(versionFile))
|
||||
{
|
||||
string[] lines = System.IO.File.ReadAllLines(versionFile);
|
||||
if (lines.Length > 0 && !string.IsNullOrEmpty(lines[0].Trim()))
|
||||
{
|
||||
return lines[0].Trim();
|
||||
}
|
||||
}
|
||||
|
||||
var downloader = ResourceDownloader.Get();
|
||||
if (downloader != null)
|
||||
{
|
||||
string resourceVersion = downloader.GetCurrentVersion();
|
||||
if (!string.IsNullOrEmpty(resourceVersion) && resourceVersion != "0.0.0")
|
||||
{
|
||||
return resourceVersion;
|
||||
}
|
||||
}
|
||||
|
||||
return Application.version;
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.LogWarning($"[SplashScreenManager] 获取版本信息失败: {e.Message}");
|
||||
return Application.version;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/TcgEngine/Scripts/Menu/SplashScreenManager.cs.meta
Normal file
11
Assets/TcgEngine/Scripts/Menu/SplashScreenManager.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 24f0b732b564f46fc8917f973e8fa11a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user