拉取资源
This commit is contained in:
@@ -12,7 +12,7 @@ namespace TcgEngine
|
||||
public class AvatarData : ScriptableObject
|
||||
{
|
||||
public string id;
|
||||
public Sprite avatar;
|
||||
public string avatar_path;
|
||||
public int sort_order;
|
||||
|
||||
public static List<AvatarData> avatar_list = new List<AvatarData>();
|
||||
@@ -29,6 +29,17 @@ namespace TcgEngine
|
||||
return a.sort_order.CompareTo(b.sort_order);
|
||||
});
|
||||
}
|
||||
|
||||
public Sprite GetAvatar()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(avatar_path))
|
||||
{
|
||||
Sprite dynamicSprite = SpriteLoader.Get()?.LoadSprite(avatar_path);
|
||||
if (dynamicSprite != null)
|
||||
return dynamicSprite;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static AvatarData Get(string id)
|
||||
{
|
||||
|
||||
@@ -36,8 +36,10 @@ namespace TcgEngine
|
||||
|
||||
[Header("Display")]
|
||||
public string title;
|
||||
public Sprite art_full;
|
||||
public Sprite art_board;
|
||||
|
||||
[Header("Dynamic Art Paths")]
|
||||
public string art_full_path;
|
||||
public string art_board_path;
|
||||
|
||||
[Header("Stats")]
|
||||
public CardType type;
|
||||
@@ -95,12 +97,34 @@ namespace TcgEngine
|
||||
|
||||
public Sprite GetBoardArt(VariantData variant)
|
||||
{
|
||||
return art_board;
|
||||
if (!string.IsNullOrEmpty(art_board_path))
|
||||
{
|
||||
Sprite dynamicSprite = SpriteLoader.Get()?.LoadSprite(art_board_path);
|
||||
if (dynamicSprite != null)
|
||||
return dynamicSprite;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Sprite GetFullArt(VariantData variant)
|
||||
{
|
||||
return art_full;
|
||||
if (!string.IsNullOrEmpty(art_full_path))
|
||||
{
|
||||
Sprite dynamicSprite = SpriteLoader.Get()?.LoadSprite(art_full_path);
|
||||
if (dynamicSprite != null)
|
||||
{
|
||||
return dynamicSprite;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"卡牌{id} 图片加载失败: {art_full_path}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"卡牌{id} art_full_path为空");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public string GetTitle()
|
||||
|
||||
@@ -12,8 +12,8 @@ namespace TcgEngine
|
||||
public class CardbackData : ScriptableObject
|
||||
{
|
||||
public string id;
|
||||
public Sprite cardback;
|
||||
public Sprite deck;
|
||||
public string cardback_path;
|
||||
public string deck_path;
|
||||
public int sort_order;
|
||||
|
||||
public static List<CardbackData> cardback_list = new List<CardbackData>();
|
||||
@@ -30,6 +30,28 @@ namespace TcgEngine
|
||||
return a.sort_order.CompareTo(b.sort_order);
|
||||
});
|
||||
}
|
||||
|
||||
public Sprite GetCardback()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(cardback_path))
|
||||
{
|
||||
Sprite dynamicSprite = SpriteLoader.Get()?.LoadSprite(cardback_path);
|
||||
if (dynamicSprite != null)
|
||||
return dynamicSprite;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Sprite GetDeck()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(deck_path))
|
||||
{
|
||||
Sprite dynamicSprite = SpriteLoader.Get()?.LoadSprite(deck_path);
|
||||
if (dynamicSprite != null)
|
||||
return dynamicSprite;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static CardbackData Get(string id)
|
||||
{
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace TcgEngine.Client
|
||||
|
||||
CardbackData cb = CardbackData.Get(player.cardback);
|
||||
if (deck_render != null && cb != null)
|
||||
deck_render.sprite = cb.deck;
|
||||
deck_render.sprite = cb.GetDeck();
|
||||
|
||||
if (deck_value != null)
|
||||
deck_value.text = player.cards_deck.Count.ToString();
|
||||
|
||||
@@ -31,8 +31,8 @@ namespace TcgEngine.Client
|
||||
|
||||
public void SetCardback(CardbackData cb)
|
||||
{
|
||||
if (cb != null && cb.cardback != null)
|
||||
card_sprite.sprite = cb.cardback;
|
||||
if (cb != null)
|
||||
card_sprite.sprite = cb.GetCardback();
|
||||
}
|
||||
|
||||
public RectTransform GetRect()
|
||||
|
||||
@@ -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:
|
||||
685
Assets/TcgEngine/Scripts/Network/ResourceDownloader.cs
Normal file
685
Assets/TcgEngine/Scripts/Network/ResourceDownloader.cs
Normal file
@@ -0,0 +1,685 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace TcgEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// 资源下载管理器
|
||||
/// </summary>
|
||||
public class ResourceDownloader : MonoBehaviour
|
||||
{
|
||||
[Header("Download Settings")]
|
||||
public string serverUrl = "https://cardcdn.ambigrat.com";
|
||||
public string resourcesEndpoint = "/test/{version}.zip";
|
||||
public string versionEndpoint = "/api/version";
|
||||
|
||||
[Header("URL Pattern Options")]
|
||||
[Tooltip("支持的占位符: {version} - 版本号")]
|
||||
public bool useVersionInFilename = true;
|
||||
[Tooltip("如果启用,会先检查版本化文件是否存在")]
|
||||
public bool validateVersionedUrl = false;
|
||||
[Tooltip("调试模式:当版本接口失败时,使用固定版本号")]
|
||||
public bool debugMode = true;
|
||||
[Tooltip("调试模式下使用的固定版本号")]
|
||||
public string debugVersion = "0.0.1";
|
||||
[Tooltip("调试模式下使用的固定MD5值")]
|
||||
public string debugMd5 = "ceb24758054d6dcf1e23ddb41811a525";
|
||||
private string currentVersion = "0.0.0";
|
||||
private string currentMd5 = "";
|
||||
private string targetVersion = "0.0.1";
|
||||
private string targetMd5 = "";
|
||||
private string persistentDataPath;
|
||||
private string spritesPath;
|
||||
|
||||
public static ResourceDownloader instance;
|
||||
|
||||
// 事件
|
||||
public event Action<float> OnDownloadProgress;
|
||||
public event Action<string> OnDownloadComplete;
|
||||
public event Action<string> OnDownloadError;
|
||||
public event Action<float> OnExtractProgress;
|
||||
public event Action OnExtractComplete;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
instance = this;
|
||||
DontDestroyOnLoad(gameObject);
|
||||
InitializePaths();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果已经存在实例,销毁这个重复的组件
|
||||
Debug.LogWarning("ResourceDownloader instance already exists, destroying duplicate");
|
||||
Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializePaths()
|
||||
{
|
||||
persistentDataPath = Application.persistentDataPath;
|
||||
spritesPath = Path.Combine(persistentDataPath, "Sprites");
|
||||
|
||||
// 确保目录存在
|
||||
if (!Directory.Exists(spritesPath))
|
||||
{
|
||||
Directory.CreateDirectory(spritesPath);
|
||||
}
|
||||
|
||||
LoadCurrentVersion();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否需要更新资源
|
||||
/// </summary>
|
||||
public async Task<bool> CheckForUpdates()
|
||||
{
|
||||
try
|
||||
{
|
||||
Debug.Log($"Starting update check. Current version: {currentVersion}, Current MD5: {currentMd5}");
|
||||
var serverVersionData = await GetServerVersionData();
|
||||
if (serverVersionData == null || string.IsNullOrEmpty(serverVersionData.version))
|
||||
{
|
||||
Debug.LogWarning("Failed to get server version");
|
||||
|
||||
// 调试模式:版本接口失败时使用固定版本号
|
||||
if (debugMode)
|
||||
{
|
||||
Debug.Log($"Debug mode enabled: using fixed version {debugVersion} and MD5 {debugMd5}");
|
||||
targetVersion = debugVersion;
|
||||
targetMd5 = debugMd5;
|
||||
|
||||
return await CheckVersionAndMd5();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
targetVersion = serverVersionData.version;
|
||||
targetMd5 = serverVersionData.md5 ?? "";
|
||||
Debug.Log($"Server version: {targetVersion}, MD5: {targetMd5}, Local version: {currentVersion}, Local MD5: {currentMd5}");
|
||||
|
||||
return await CheckVersionAndMd5();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"Error checking for updates: {e.Message}");
|
||||
|
||||
// 调试模式:出现异常时也尝试使用固定版本
|
||||
if (debugMode)
|
||||
{
|
||||
Debug.Log($"Debug mode: attempting to use version {debugVersion} despite error");
|
||||
targetVersion = debugVersion;
|
||||
targetMd5 = debugMd5;
|
||||
|
||||
return await CheckVersionAndMd5();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查版本和MD5,决定是否需要下载
|
||||
/// </summary>
|
||||
private async Task<bool> CheckVersionAndMd5()
|
||||
{
|
||||
// 检查版本是否不同
|
||||
if (currentVersion != targetVersion)
|
||||
{
|
||||
Debug.Log($"Version mismatch. Current: {currentVersion}, Target: {targetVersion}");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 检查本地文件是否存在
|
||||
if (!Directory.Exists(spritesPath) || Directory.GetFiles(spritesPath, "*", SearchOption.AllDirectories).Length == 0)
|
||||
{
|
||||
Debug.Log("Local sprites not found, need to download");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 版本相同,检查MD5
|
||||
if (string.IsNullOrEmpty(targetMd5))
|
||||
{
|
||||
Debug.Log("No target MD5 provided, assuming files are correct");
|
||||
return false;
|
||||
}
|
||||
|
||||
Debug.Log($"版本匹配,开始检查MD5校验...");
|
||||
Debug.Log($"当前版本: {currentVersion}");
|
||||
Debug.Log($"目标版本: {targetVersion}");
|
||||
Debug.Log($"保存的MD5: {currentMd5}");
|
||||
Debug.Log($"目标MD5: {targetMd5}");
|
||||
|
||||
string localMd5 = await CalculateDirectoryMd5(spritesPath);
|
||||
|
||||
if (localMd5 != targetMd5)
|
||||
{
|
||||
Debug.LogWarning($"🚨 MD5校验失败!");
|
||||
Debug.LogWarning($"本地计算MD5: {localMd5}");
|
||||
Debug.LogWarning($"期望的MD5: {targetMd5}");
|
||||
Debug.Log("正在删除损坏的文件并重新下载...");
|
||||
|
||||
// 删除损坏的文件
|
||||
if (Directory.Exists(spritesPath))
|
||||
{
|
||||
Directory.Delete(spritesPath, true);
|
||||
}
|
||||
|
||||
return true; // 需要重新下载
|
||||
}
|
||||
|
||||
Debug.Log($"✅ MD5校验通过: {localMd5}");
|
||||
Debug.Log("文件完整性验证成功,无需下载");
|
||||
return false; // 无需下载
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算目录下所有文件的MD5和
|
||||
/// </summary>
|
||||
private async Task<string> CalculateDirectoryMd5(string directoryPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!Directory.Exists(directoryPath))
|
||||
return "";
|
||||
|
||||
var files = Directory.GetFiles(directoryPath, "*", SearchOption.AllDirectories);
|
||||
if (files.Length == 0)
|
||||
return "";
|
||||
|
||||
Debug.Log($"=== 开始计算目录MD5 ===");
|
||||
Debug.Log($"目录路径: {directoryPath}");
|
||||
Debug.Log($"文件数量: {files.Length}");
|
||||
|
||||
// 按路径排序确保一致性
|
||||
Array.Sort(files);
|
||||
|
||||
// 打印前几个文件作为示例
|
||||
Debug.Log("文件列表示例:");
|
||||
for (int i = 0; i < Math.Min(5, files.Length); i++)
|
||||
{
|
||||
string relativePath = files[i].Substring(directoryPath.Length + 1).Replace('\\', '/');
|
||||
Debug.Log($" [{i+1}] {relativePath}");
|
||||
}
|
||||
if (files.Length > 5)
|
||||
{
|
||||
Debug.Log($" ... 还有 {files.Length - 5} 个文件");
|
||||
}
|
||||
|
||||
using (var md5 = System.Security.Cryptography.MD5.Create())
|
||||
{
|
||||
foreach (string file in files)
|
||||
{
|
||||
// 只处理相对路径部分
|
||||
string relativePath = file.Substring(directoryPath.Length + 1).Replace('\\', '/');
|
||||
byte[] pathBytes = System.Text.Encoding.UTF8.GetBytes(relativePath);
|
||||
md5.TransformBlock(pathBytes, 0, pathBytes.Length, null, 0);
|
||||
|
||||
// 读取文件内容
|
||||
byte[] fileBytes = File.ReadAllBytes(file);
|
||||
md5.TransformBlock(fileBytes, 0, fileBytes.Length, null, 0);
|
||||
|
||||
// 每10个文件yield一次,避免阻塞
|
||||
if (Array.IndexOf(files, file) % 10 == 0)
|
||||
{
|
||||
await Task.Yield();
|
||||
}
|
||||
}
|
||||
|
||||
// 完成哈希计算
|
||||
md5.TransformFinalBlock(new byte[0], 0, 0);
|
||||
string result = BitConverter.ToString(md5.Hash).Replace("-", "").ToLowerInvariant();
|
||||
|
||||
Debug.Log($"=== MD5计算完成 ===");
|
||||
Debug.Log($"本地计算的MD5: {result}");
|
||||
Debug.Log($"目标MD5: {targetMd5}");
|
||||
Debug.Log($"MD5匹配: {(result == targetMd5 ? "✅ 是" : "❌ 否")}");
|
||||
Debug.Log($"===================");
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"Error calculating directory MD5: {e.Message}");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构建版本化的下载URL
|
||||
/// </summary>
|
||||
private string BuildVersionedDownloadUrl(string version)
|
||||
{
|
||||
string targetFileName;
|
||||
|
||||
if (!useVersionInFilename)
|
||||
{
|
||||
// 不使用版本化文件名时,统一使用"sprites"
|
||||
targetFileName = "sprites";
|
||||
}
|
||||
else if (string.IsNullOrEmpty(version))
|
||||
{
|
||||
// 如果版本为空,使用调试版本
|
||||
targetFileName = debugVersion;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 使用实际版本号
|
||||
targetFileName = version;
|
||||
}
|
||||
|
||||
string endpoint = resourcesEndpoint.Replace("{version}", targetFileName);
|
||||
string url = serverUrl + endpoint;
|
||||
|
||||
Debug.Log($"Built download URL: {url} (version: {version}, filename: {targetFileName})");
|
||||
return url;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证版本化URL是否存在(可选)
|
||||
/// </summary>
|
||||
private async Task<bool> ValidateVersionedUrl(string url)
|
||||
{
|
||||
if (!validateVersionedUrl)
|
||||
return true;
|
||||
|
||||
try
|
||||
{
|
||||
using (UnityWebRequest request = UnityWebRequest.Head(url))
|
||||
{
|
||||
var operation = request.SendWebRequest();
|
||||
|
||||
while (!operation.isDone)
|
||||
{
|
||||
await Task.Yield();
|
||||
}
|
||||
|
||||
if (request.result == UnityWebRequest.Result.Success)
|
||||
{
|
||||
Debug.Log($"Validated versioned URL: {url}");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"Versioned URL not found: {url} - {request.error}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"Error validating URL {url}: {e.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取服务器版本数据
|
||||
/// </summary>
|
||||
private async Task<ResourceVersionResponse> GetServerVersionData()
|
||||
{
|
||||
// 从NetworkData获取游戏服务器地址
|
||||
string gameServerUrl = NetworkData.Get().api_url;
|
||||
if (string.IsNullOrEmpty(gameServerUrl))
|
||||
{
|
||||
Debug.LogError("Failed to get game server URL from NetworkData");
|
||||
return null;
|
||||
}
|
||||
|
||||
// 构建完整的版本检查URL
|
||||
string protocol = NetworkData.Get().api_https ? "https://" : "http://";
|
||||
string url = protocol + gameServerUrl + versionEndpoint;
|
||||
Debug.Log($"Version check URL: {url}");
|
||||
using (UnityWebRequest request = UnityWebRequest.Get(url))
|
||||
{
|
||||
var operation = request.SendWebRequest();
|
||||
|
||||
while (!operation.isDone)
|
||||
{
|
||||
await Task.Yield();
|
||||
}
|
||||
|
||||
if (request.result == UnityWebRequest.Result.Success)
|
||||
{
|
||||
try
|
||||
{
|
||||
var versionData = JsonUtility.FromJson<ResourceVersionResponse>(request.downloadHandler.text);
|
||||
return versionData;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"Failed to parse version response: {e.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"Failed to get version: {request.error}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 下载并更新资源
|
||||
/// </summary>
|
||||
public async Task<bool> DownloadAndUpdateResources()
|
||||
{
|
||||
try
|
||||
{
|
||||
string zipFilePath = Path.Combine(persistentDataPath, $"{targetVersion}.zip");
|
||||
|
||||
// 构建版本化的下载URL
|
||||
string downloadUrl = BuildVersionedDownloadUrl(targetVersion);
|
||||
|
||||
// 验证URL是否存在(可选)
|
||||
if (validateVersionedUrl)
|
||||
{
|
||||
bool urlExists = await ValidateVersionedUrl(downloadUrl);
|
||||
if (!urlExists)
|
||||
{
|
||||
OnDownloadError?.Invoke($"Versioned resource not found for version {targetVersion}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 下载压缩包
|
||||
bool downloadSuccess = await DownloadFile(downloadUrl, zipFilePath);
|
||||
if (!downloadSuccess)
|
||||
{
|
||||
OnDownloadError?.Invoke("Failed to download resources");
|
||||
return false;
|
||||
}
|
||||
|
||||
OnDownloadComplete?.Invoke(zipFilePath);
|
||||
|
||||
// 解压文件
|
||||
bool extractSuccess = await ExtractZipFile(zipFilePath, spritesPath);
|
||||
if (!extractSuccess)
|
||||
{
|
||||
OnDownloadError?.Invoke("Failed to extract resources");
|
||||
return false;
|
||||
}
|
||||
|
||||
OnExtractComplete?.Invoke();
|
||||
|
||||
// 清理下载的压缩包
|
||||
if (File.Exists(zipFilePath))
|
||||
{
|
||||
File.Delete(zipFilePath);
|
||||
}
|
||||
|
||||
// 更新版本信息
|
||||
SaveCurrentVersion(targetVersion, targetMd5);
|
||||
currentVersion = targetVersion;
|
||||
currentMd5 = targetMd5;
|
||||
|
||||
Debug.Log($"Resources updated successfully to version {currentVersion}");
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"Error downloading/updating resources: {e.Message}");
|
||||
OnDownloadError?.Invoke(e.Message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 下载文件
|
||||
/// </summary>
|
||||
private async Task<bool> DownloadFile(string url, string filePath)
|
||||
{
|
||||
using (UnityWebRequest request = UnityWebRequest.Get(url))
|
||||
{
|
||||
var operation = request.SendWebRequest();
|
||||
|
||||
while (!operation.isDone)
|
||||
{
|
||||
OnDownloadProgress?.Invoke(request.downloadProgress);
|
||||
await Task.Yield();
|
||||
}
|
||||
|
||||
if (request.result == UnityWebRequest.Result.Success)
|
||||
{
|
||||
File.WriteAllBytes(filePath, request.downloadHandler.data);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"Download failed: {request.error}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解压ZIP文件
|
||||
/// </summary>
|
||||
private async Task<bool> ExtractZipFile(string zipFilePath, string extractPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 清空目标目录
|
||||
if (Directory.Exists(extractPath))
|
||||
{
|
||||
Directory.Delete(extractPath, true);
|
||||
}
|
||||
Directory.CreateDirectory(extractPath);
|
||||
|
||||
using (var archive = ZipFile.OpenRead(zipFilePath))
|
||||
{
|
||||
int totalEntries = archive.Entries.Count;
|
||||
int processedEntries = 0;
|
||||
|
||||
foreach (var entry in archive.Entries)
|
||||
{
|
||||
// 跳过目录条目
|
||||
if (string.IsNullOrEmpty(entry.Name))
|
||||
continue;
|
||||
|
||||
string entryPath = Path.Combine(extractPath, entry.FullName);
|
||||
string directoryName = Path.GetDirectoryName(entryPath);
|
||||
|
||||
if (!string.IsNullOrEmpty(directoryName) && !Directory.Exists(directoryName))
|
||||
{
|
||||
Directory.CreateDirectory(directoryName);
|
||||
}
|
||||
|
||||
using (var entryStream = entry.Open())
|
||||
using (var outputStream = File.Create(entryPath))
|
||||
{
|
||||
await entryStream.CopyToAsync(outputStream);
|
||||
}
|
||||
|
||||
processedEntries++;
|
||||
OnExtractProgress?.Invoke((float)processedEntries / totalEntries);
|
||||
|
||||
if (processedEntries % 10 == 0) // 每10个文件yield一次
|
||||
{
|
||||
await Task.Yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"Extract failed: {e.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载当前版本信息
|
||||
/// </summary>
|
||||
private void LoadCurrentVersion()
|
||||
{
|
||||
string versionFile = Path.Combine(persistentDataPath, "version.txt");
|
||||
if (File.Exists(versionFile))
|
||||
{
|
||||
string[] lines = File.ReadAllLines(versionFile);
|
||||
if (lines.Length > 0)
|
||||
{
|
||||
currentVersion = lines[0].Trim();
|
||||
}
|
||||
if (lines.Length > 1)
|
||||
{
|
||||
currentMd5 = lines[1].Trim();
|
||||
}
|
||||
Debug.Log($"Loaded current version: {currentVersion}, MD5: {currentMd5}");
|
||||
}
|
||||
else
|
||||
{
|
||||
currentVersion = "0.0.0";
|
||||
currentMd5 = "";
|
||||
Debug.Log($"No version file found, using defaults: {currentVersion}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存当前版本信息
|
||||
/// </summary>
|
||||
private void SaveCurrentVersion(string version, string md5 = "")
|
||||
{
|
||||
string versionFile = Path.Combine(persistentDataPath, "version.txt");
|
||||
string content = version;
|
||||
if (!string.IsNullOrEmpty(md5))
|
||||
{
|
||||
content += "\n" + md5;
|
||||
}
|
||||
File.WriteAllText(versionFile, content);
|
||||
Debug.Log($"Saved version: {version}, MD5: {md5}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取本地Sprite资源路径
|
||||
/// </summary>
|
||||
public string GetLocalSpritePath(string relativePath)
|
||||
{
|
||||
return Path.Combine(spritesPath, relativePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查本地资源是否存在
|
||||
/// </summary>
|
||||
public bool HasLocalResources()
|
||||
{
|
||||
return Directory.Exists(spritesPath) &&
|
||||
Directory.GetFiles(spritesPath, "*", SearchOption.AllDirectories).Length > 0;
|
||||
}
|
||||
|
||||
public string GetCurrentVersion()
|
||||
{
|
||||
return currentVersion;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定版本的下载URL(用于调试)
|
||||
/// </summary>
|
||||
public string GetDownloadUrlForVersion(string version)
|
||||
{
|
||||
return BuildVersionedDownloadUrl(version);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前目标版本的下载URL
|
||||
/// </summary>
|
||||
public string GetCurrentDownloadUrl()
|
||||
{
|
||||
return BuildVersionedDownloadUrl(targetVersion);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取本地Sprites目录的完整路径(用于调试)
|
||||
/// </summary>
|
||||
public string GetSpritesDirectoryPath()
|
||||
{
|
||||
return spritesPath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 手动计算并打印当前Sprites目录的MD5
|
||||
/// </summary>
|
||||
public async void CalculateAndLogCurrentMd5()
|
||||
{
|
||||
Debug.Log("=== 手动计算当前Sprites目录MD5 ===");
|
||||
if (!Directory.Exists(spritesPath))
|
||||
{
|
||||
Debug.LogWarning("Sprites目录不存在!");
|
||||
return;
|
||||
}
|
||||
|
||||
string calculatedMd5 = await CalculateDirectoryMd5(spritesPath);
|
||||
Debug.Log($"手动计算结果: {calculatedMd5}");
|
||||
Debug.Log($"当前保存的MD5: {currentMd5}");
|
||||
Debug.Log($"调试MD5: {debugMd5}");
|
||||
Debug.Log("================================");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 打印本地资源路径信息
|
||||
/// </summary>
|
||||
public void LogResourcePaths()
|
||||
{
|
||||
Debug.Log($"=== Resource Paths ===");
|
||||
Debug.Log($"persistentDataPath: {persistentDataPath}");
|
||||
Debug.Log($"Sprites Directory: {spritesPath}");
|
||||
Debug.Log($"Directory Exists: {Directory.Exists(spritesPath)}");
|
||||
|
||||
if (Directory.Exists(spritesPath))
|
||||
{
|
||||
var files = Directory.GetFiles(spritesPath, "*", SearchOption.AllDirectories);
|
||||
Debug.Log($"Total files in Sprites: {files.Length}");
|
||||
|
||||
// 显示前10个文件作为示例
|
||||
for (int i = 0; i < Math.Min(10, files.Length); i++)
|
||||
{
|
||||
string relativePath = files[i].Substring(spritesPath.Length + 1);
|
||||
Debug.Log($" {relativePath}");
|
||||
}
|
||||
|
||||
if (files.Length > 10)
|
||||
{
|
||||
Debug.Log($" ... and {files.Length - 10} more files");
|
||||
}
|
||||
}
|
||||
Debug.Log($"======================");
|
||||
}
|
||||
|
||||
public static ResourceDownloader Get()
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
// 如果没有实例,创建一个新的
|
||||
GameObject go = new GameObject("ResourceDownloader");
|
||||
instance = go.AddComponent<ResourceDownloader>();
|
||||
DontDestroyOnLoad(go);
|
||||
Debug.Log("Created new ResourceDownloader instance");
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 资源版本响应数据结构
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class ResourceVersionResponse
|
||||
{
|
||||
public string version;
|
||||
public string md5;
|
||||
public string description;
|
||||
public long timestamp;
|
||||
}
|
||||
}
|
||||
11
Assets/TcgEngine/Scripts/Network/ResourceDownloader.cs.meta
Normal file
11
Assets/TcgEngine/Scripts/Network/ResourceDownloader.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: da41884ccee8c42b594e97ccc928ddf2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
187
Assets/TcgEngine/Scripts/Tools/ResourcePathHelper.cs
Normal file
187
Assets/TcgEngine/Scripts/Tools/ResourcePathHelper.cs
Normal file
@@ -0,0 +1,187 @@
|
||||
using UnityEngine;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using System.IO;
|
||||
#endif
|
||||
|
||||
namespace TcgEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// 自动设置卡牌、头像、卡背的资源路径
|
||||
/// </summary>
|
||||
public class ResourcePathHelper : MonoBehaviour
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
|
||||
[MenuItem("TcgEngine/Tools/Setup Cards Data Paths")]
|
||||
public static void SetupCardsDataPaths()
|
||||
{
|
||||
string[] cardGuids = AssetDatabase.FindAssets("t:CardData");
|
||||
int updated = 0;
|
||||
|
||||
foreach (string guid in cardGuids)
|
||||
{
|
||||
string assetPath = AssetDatabase.GUIDToAssetPath(guid);
|
||||
CardData card = AssetDatabase.LoadAssetAtPath<CardData>(assetPath);
|
||||
|
||||
if (card != null)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
card.art_full_path = $"Cards/{card.id}.png";
|
||||
Debug.Log($"Card {card.id}: set art_full_path = {card.art_full_path}");
|
||||
changed = true;
|
||||
|
||||
card.art_board_path = $"CardsBoard/{card.id}_board.png";
|
||||
Debug.Log($"Card {card.id}: set art_board_path = {card.art_board_path}");
|
||||
changed = true;
|
||||
|
||||
if (changed)
|
||||
{
|
||||
EditorUtility.SetDirty(card);
|
||||
updated++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
|
||||
[MenuItem("TcgEngine/Tools/Setup Avatar Data Paths")]
|
||||
public static void SetupAvatarDataPaths()
|
||||
{
|
||||
string[] avatarGuids = AssetDatabase.FindAssets("t:AvatarData");
|
||||
int updated = 0;
|
||||
|
||||
foreach (string guid in avatarGuids)
|
||||
{
|
||||
string assetPath = AssetDatabase.GUIDToAssetPath(guid);
|
||||
AvatarData avatar = AssetDatabase.LoadAssetAtPath<AvatarData>(assetPath);
|
||||
|
||||
if (avatar != null)
|
||||
{
|
||||
avatar.avatar_path = $"Avatar/{avatar.id}.png";
|
||||
Debug.Log($"Avatar {avatar.id}: set avatar_path = {avatar.avatar_path}");
|
||||
|
||||
EditorUtility.SetDirty(avatar);
|
||||
updated++;
|
||||
}
|
||||
}
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
|
||||
[MenuItem("TcgEngine/Tools/Setup Cardback Data Paths")]
|
||||
public static void SetupCardbackDataPaths()
|
||||
{
|
||||
string[] cardbackGuids = AssetDatabase.FindAssets("t:CardbackData");
|
||||
int updated = 0;
|
||||
|
||||
foreach (string guid in cardbackGuids)
|
||||
{
|
||||
string assetPath = AssetDatabase.GUIDToAssetPath(guid);
|
||||
CardbackData cardback = AssetDatabase.LoadAssetAtPath<CardbackData>(assetPath);
|
||||
|
||||
if (cardback != null)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
int lastIndex = cardback.id.LastIndexOf('_');
|
||||
string cardbackId = "";
|
||||
|
||||
if (lastIndex != -1)
|
||||
{
|
||||
cardbackId = cardback.id.Substring(lastIndex + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
cardbackId = cardback.id;
|
||||
}
|
||||
|
||||
cardback.cardback_path = $"Cardbacks/cardback_{cardbackId}.png";
|
||||
Debug.Log($"Cardback {cardback.id} set cardback_path = {cardback.cardback_path}");
|
||||
changed = true;
|
||||
|
||||
cardback.deck_path = $"Cardbacks/deck_{cardbackId}.png";
|
||||
Debug.Log($"Cardback {cardback.id} set deck_path = {cardback.deck_path}");
|
||||
if (changed)
|
||||
{
|
||||
EditorUtility.SetDirty(cardback);
|
||||
updated++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将Unity资源路径转换为Sprites相对路径
|
||||
/// </summary>
|
||||
private static string ConvertUnityPathToSpritePath(string unityPath)
|
||||
{
|
||||
if (string.IsNullOrEmpty(unityPath))
|
||||
return "";
|
||||
|
||||
// 查找Sprites文件夹在路径中的位置
|
||||
int spritesIndex = unityPath.IndexOf("Sprites/");
|
||||
if (spritesIndex >= 0)
|
||||
{
|
||||
// 提取Sprites/之后的部分
|
||||
string relativePath = unityPath.Substring(spritesIndex + "Sprites/".Length);
|
||||
return relativePath;
|
||||
}
|
||||
|
||||
return Path.GetFileName(unityPath);
|
||||
}
|
||||
|
||||
[MenuItem("TcgEngine/Tools/Clear Dynamic Sprite Paths")]
|
||||
public static void ClearDynamicSpritePaths()
|
||||
{
|
||||
// 清除卡牌数据路径
|
||||
string[] cardGuids = AssetDatabase.FindAssets("t:CardData");
|
||||
foreach (string guid in cardGuids)
|
||||
{
|
||||
string assetPath = AssetDatabase.GUIDToAssetPath(guid);
|
||||
CardData card = AssetDatabase.LoadAssetAtPath<CardData>(assetPath);
|
||||
if (card != null)
|
||||
{
|
||||
card.art_full_path = "";
|
||||
card.art_board_path = "";
|
||||
EditorUtility.SetDirty(card);
|
||||
}
|
||||
}
|
||||
|
||||
// 清除头像数据路径
|
||||
string[] avatarGuids = AssetDatabase.FindAssets("t:AvatarData");
|
||||
foreach (string guid in avatarGuids)
|
||||
{
|
||||
string assetPath = AssetDatabase.GUIDToAssetPath(guid);
|
||||
AvatarData avatar = AssetDatabase.LoadAssetAtPath<AvatarData>(assetPath);
|
||||
if (avatar != null)
|
||||
{
|
||||
avatar.avatar_path = "";
|
||||
EditorUtility.SetDirty(avatar);
|
||||
}
|
||||
}
|
||||
|
||||
// 清除卡背数据路径
|
||||
string[] cardbackGuids = AssetDatabase.FindAssets("t:CardbackData");
|
||||
foreach (string guid in cardbackGuids)
|
||||
{
|
||||
string assetPath = AssetDatabase.GUIDToAssetPath(guid);
|
||||
CardbackData cardback = AssetDatabase.LoadAssetAtPath<CardbackData>(assetPath);
|
||||
if (cardback != null)
|
||||
{
|
||||
cardback.cardback_path = "";
|
||||
cardback.deck_path = "";
|
||||
EditorUtility.SetDirty(cardback);
|
||||
}
|
||||
}
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
Debug.Log("Clear Success");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
11
Assets/TcgEngine/Scripts/Tools/ResourcePathHelper.cs.meta
Normal file
11
Assets/TcgEngine/Scripts/Tools/ResourcePathHelper.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 354fdcbafb88747fabb12a3d8e719722
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
321
Assets/TcgEngine/Scripts/Tools/SpriteLoader.cs
Normal file
321
Assets/TcgEngine/Scripts/Tools/SpriteLoader.cs
Normal file
@@ -0,0 +1,321 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TcgEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// 动态Sprite加载器,支持从本地下载的资源中加载图片
|
||||
/// </summary>
|
||||
public class SpriteLoader : MonoBehaviour
|
||||
{
|
||||
private static SpriteLoader instance;
|
||||
private Dictionary<string, Sprite> spriteCache = new Dictionary<string, Sprite>();
|
||||
private Dictionary<string, Texture2D> textureCache = new Dictionary<string, Texture2D>();
|
||||
|
||||
public static SpriteLoader Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
GameObject go = new GameObject("SpriteLoader");
|
||||
instance = go.AddComponent<SpriteLoader>();
|
||||
DontDestroyOnLoad(go);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
instance = this;
|
||||
DontDestroyOnLoad(gameObject);
|
||||
}
|
||||
else if (instance != this)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从本地文件加载Sprite
|
||||
/// </summary>
|
||||
/// <param name="relativePath">相对于Sprites文件夹的路径</param>
|
||||
/// <returns>加载的Sprite,失败返回null</returns>
|
||||
public Sprite LoadSprite(string relativePath)
|
||||
{
|
||||
if (string.IsNullOrEmpty(relativePath))
|
||||
{
|
||||
Debug.LogWarning("[SpriteLoader] Empty relativePath provided");
|
||||
return null;
|
||||
}
|
||||
|
||||
Debug.Log($"[SpriteLoader] Loading sprite: {relativePath}");
|
||||
|
||||
// 检查缓存
|
||||
if (spriteCache.ContainsKey(relativePath))
|
||||
{
|
||||
Debug.Log($"[SpriteLoader] Found in cache: {relativePath}");
|
||||
return spriteCache[relativePath];
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// 先尝试从下载的本地资源加载
|
||||
string localPath = GetLocalSpritePath(relativePath);
|
||||
Debug.Log($"[SpriteLoader] Checking local path: {localPath}");
|
||||
|
||||
if (File.Exists(localPath))
|
||||
{
|
||||
Debug.Log($"[SpriteLoader] Local file exists, loading from: {localPath}");
|
||||
Sprite sprite = LoadSpriteFromFile(localPath);
|
||||
if (sprite != null)
|
||||
{
|
||||
Debug.Log($"[SpriteLoader] Successfully loaded from local file: {relativePath}");
|
||||
spriteCache[relativePath] = sprite;
|
||||
return sprite;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"[SpriteLoader] Failed to load sprite from local file: {localPath}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"[SpriteLoader] Local file does not exist: {localPath}");
|
||||
}
|
||||
|
||||
// 如果本地文件不存在,尝试从Resources加载(fallback)
|
||||
Debug.Log($"[SpriteLoader] Trying Resources fallback for: {relativePath}");
|
||||
Sprite fallbackSprite = LoadSpriteFromResources(relativePath);
|
||||
if (fallbackSprite != null)
|
||||
{
|
||||
Debug.Log($"[SpriteLoader] Successfully loaded from Resources: {relativePath}");
|
||||
spriteCache[relativePath] = fallbackSprite;
|
||||
return fallbackSprite;
|
||||
}
|
||||
|
||||
Debug.LogWarning($"[SpriteLoader] Failed to load sprite from both local and Resources: {relativePath}");
|
||||
return null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"[SpriteLoader] Error loading sprite {relativePath}: {e.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从文件系统加载Sprite
|
||||
/// </summary>
|
||||
private Sprite LoadSpriteFromFile(string filePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 加载纹理
|
||||
Texture2D texture = LoadTextureFromFile(filePath);
|
||||
if (texture == null)
|
||||
return null;
|
||||
|
||||
// 创建Sprite
|
||||
Sprite sprite = Sprite.Create(
|
||||
texture,
|
||||
new Rect(0, 0, texture.width, texture.height),
|
||||
new Vector2(0.5f, 0.5f)
|
||||
);
|
||||
|
||||
return sprite;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"Error loading sprite from file {filePath}: {e.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从文件加载纹理
|
||||
/// </summary>
|
||||
private Texture2D LoadTextureFromFile(string filePath)
|
||||
{
|
||||
if (textureCache.ContainsKey(filePath))
|
||||
{
|
||||
return textureCache[filePath];
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
byte[] fileData = File.ReadAllBytes(filePath);
|
||||
Texture2D texture = new Texture2D(2, 2);
|
||||
|
||||
if (texture.LoadImage(fileData))
|
||||
{
|
||||
textureCache[filePath] = texture;
|
||||
return texture;
|
||||
}
|
||||
else
|
||||
{
|
||||
Destroy(texture);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"Error loading texture from file {filePath}: {e.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从Resources文件夹加载Sprite(fallback)
|
||||
/// </summary>
|
||||
private Sprite LoadSpriteFromResources(string relativePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 移除文件扩展名
|
||||
string resourcePath = Path.ChangeExtension(relativePath, null);
|
||||
|
||||
// 尝试直接加载Sprite
|
||||
Sprite sprite = Resources.Load<Sprite>(resourcePath);
|
||||
if (sprite != null)
|
||||
return sprite;
|
||||
|
||||
// 如果直接加载失败,尝试加载Texture2D然后转换
|
||||
Texture2D texture = Resources.Load<Texture2D>(resourcePath);
|
||||
if (texture != null)
|
||||
{
|
||||
return Sprite.Create(
|
||||
texture,
|
||||
new Rect(0, 0, texture.width, texture.height),
|
||||
new Vector2(0.5f, 0.5f)
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"Error loading sprite from resources {relativePath}: {e.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取本地Sprite文件路径
|
||||
/// </summary>
|
||||
private string GetLocalSpritePath(string relativePath)
|
||||
{
|
||||
if (ResourceDownloader.Get() != null)
|
||||
{
|
||||
return ResourceDownloader.Get().GetLocalSpritePath(relativePath);
|
||||
}
|
||||
|
||||
// Fallback路径
|
||||
string basePath = Path.Combine(Application.persistentDataPath, "Sprites");
|
||||
return Path.Combine(basePath, relativePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理缓存
|
||||
/// </summary>
|
||||
public void ClearCache()
|
||||
{
|
||||
foreach (var sprite in spriteCache.Values)
|
||||
{
|
||||
if (sprite != null)
|
||||
Destroy(sprite);
|
||||
}
|
||||
spriteCache.Clear();
|
||||
|
||||
foreach (var texture in textureCache.Values)
|
||||
{
|
||||
if (texture != null)
|
||||
Destroy(texture);
|
||||
}
|
||||
textureCache.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 预加载指定目录下的所有图片
|
||||
/// </summary>
|
||||
public void PreloadSprites(string directory)
|
||||
{
|
||||
try
|
||||
{
|
||||
string localDir = GetLocalSpritePath(directory);
|
||||
if (!Directory.Exists(localDir))
|
||||
return;
|
||||
|
||||
string[] files = Directory.GetFiles(localDir, "*.png", SearchOption.AllDirectories);
|
||||
foreach (string file in files)
|
||||
{
|
||||
string relativePath = GetRelativePath(file);
|
||||
LoadSprite(relativePath);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"Error preloading sprites from {directory}: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取相对路径
|
||||
/// </summary>
|
||||
private string GetRelativePath(string fullPath)
|
||||
{
|
||||
string spritesPath = GetLocalSpritePath("");
|
||||
if (fullPath.StartsWith(spritesPath))
|
||||
{
|
||||
return fullPath.Substring(spritesPath.Length + 1);
|
||||
}
|
||||
return fullPath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查Sprite是否存在
|
||||
/// </summary>
|
||||
public bool SpriteExists(string relativePath)
|
||||
{
|
||||
if (spriteCache.ContainsKey(relativePath))
|
||||
return true;
|
||||
|
||||
string localPath = GetLocalSpritePath(relativePath);
|
||||
if (File.Exists(localPath))
|
||||
return true;
|
||||
|
||||
// 检查Resources
|
||||
string resourcePath = Path.ChangeExtension(relativePath, null);
|
||||
Sprite sprite = Resources.Load<Sprite>(resourcePath);
|
||||
if (sprite != null)
|
||||
{
|
||||
Resources.UnloadAsset(sprite);
|
||||
return true;
|
||||
}
|
||||
|
||||
Texture2D texture = Resources.Load<Texture2D>(resourcePath);
|
||||
if (texture != null)
|
||||
{
|
||||
Resources.UnloadAsset(texture);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
ClearCache();
|
||||
}
|
||||
|
||||
public static SpriteLoader Get()
|
||||
{
|
||||
return Instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/TcgEngine/Scripts/Tools/SpriteLoader.cs.meta
Normal file
11
Assets/TcgEngine/Scripts/Tools/SpriteLoader.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8a6288ab659a946d2a8819eb4d8fbb41
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -39,7 +39,7 @@ namespace TcgEngine.UI
|
||||
|
||||
if (avatar != null)
|
||||
{
|
||||
avatar_img.sprite = avatar.avatar;
|
||||
avatar_img.sprite = avatar.GetAvatar();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace TcgEngine.UI
|
||||
|
||||
if (cardback != null)
|
||||
{
|
||||
cardback_img.sprite = cardback.cardback;
|
||||
cardback_img.sprite = cardback.GetCardback();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -89,9 +89,9 @@ namespace TcgEngine.UI
|
||||
AvatarData avat1 = AvatarData.Get(player.avatar);
|
||||
AvatarData avat2 = AvatarData.Get(oplayer.avatar);
|
||||
if(avat1 != null)
|
||||
player_avatar.sprite = avat1.avatar;
|
||||
player_avatar.sprite = avat1.GetAvatar();
|
||||
if (avat2 != null)
|
||||
other_avatar.sprite = avat2.avatar;
|
||||
other_avatar.sprite = avat2.GetAvatar();
|
||||
|
||||
if (pwinner != null && pwinner == player)
|
||||
winner_text.text = "Victory";
|
||||
|
||||
Reference in New Issue
Block a user