using UnityEngine;
|
using UnityEngine.UI;
|
using Cysharp.Threading.Tasks;
|
using System;
|
using System.Threading;
|
|
/// <summary>
|
/// 战斗加载界面,显示战斗资源加载进度。
|
/// 在战斗资源异步加载期间展示,加载完成后自动关闭。
|
/// </summary>
|
public class BattleLoadingWin : UIBase
|
{
|
[SerializeField] private Slider m_ProgressSlider;
|
[SerializeField] private Text m_ProgressText;
|
[SerializeField] private Text m_TipText;
|
|
private float _currentProgress;
|
private float _targetProgress;
|
private bool _isComplete;
|
|
/// <summary>
|
/// 创建 IProgress<float> 适配器,用于集成异步加载的进度回报。
|
/// </summary>
|
public IProgress<float> CreateProgressReporter()
|
{
|
return new BattleLoadingProgress(this);
|
}
|
|
protected override void InitComponent()
|
{
|
base.InitComponent();
|
_currentProgress = 0f;
|
_targetProgress = 0f;
|
_isComplete = false;
|
}
|
|
protected override void OnPreOpen()
|
{
|
base.OnPreOpen();
|
_currentProgress = 0f;
|
_targetProgress = 0f;
|
_isComplete = false;
|
UpdateUI();
|
RefreshTip();
|
}
|
|
/// <summary>
|
/// 设置加载进度 (0.0 ~ 1.0)。
|
/// </summary>
|
public void SetProgress(float progress)
|
{
|
_targetProgress = Mathf.Clamp01(progress);
|
if (_targetProgress >= 1f)
|
{
|
_isComplete = true;
|
}
|
}
|
|
/// <summary>
|
/// 直接设置进度并刷新 UI(无平滑过渡)。
|
/// </summary>
|
public void SetProgressDirectly(float progress)
|
{
|
_targetProgress = Mathf.Clamp01(progress);
|
_currentProgress = _targetProgress;
|
UpdateUI();
|
|
if (_targetProgress >= 1f)
|
{
|
_isComplete = true;
|
}
|
}
|
|
private void LateUpdate()
|
{
|
if (Mathf.Abs(_currentProgress - _targetProgress) > 0.001f)
|
{
|
_currentProgress = Mathf.Lerp(_currentProgress, _targetProgress, Time.deltaTime * 5f);
|
|
// 接近目标时直接对齐,避免无限趋近
|
if (Mathf.Abs(_currentProgress - _targetProgress) < 0.005f)
|
{
|
_currentProgress = _targetProgress;
|
}
|
|
UpdateUI();
|
}
|
|
if (_isComplete && _currentProgress >= 0.99f)
|
{
|
_currentProgress = 1f;
|
UpdateUI();
|
OnLoadComplete();
|
}
|
}
|
|
private void UpdateUI()
|
{
|
if (m_ProgressSlider != null)
|
{
|
m_ProgressSlider.value = _currentProgress;
|
}
|
|
if (m_ProgressText != null)
|
{
|
m_ProgressText.text = $"{(int)(_currentProgress * 100)}%";
|
}
|
}
|
|
private void RefreshTip()
|
{
|
if (m_TipText != null && GeneralDefine.loadingTips != null && GeneralDefine.loadingTips.Length > 0)
|
{
|
var randomIndex = UnityEngine.Random.Range(0, GeneralDefine.loadingTips.Length);
|
m_TipText.text = Language.Get(GeneralDefine.loadingTips[randomIndex]);
|
}
|
}
|
|
private void OnLoadComplete()
|
{
|
// 延迟关闭,让玩家看到 100% 状态
|
CompleteAndCloseAsync().Forget();
|
}
|
|
private async UniTask CompleteAndCloseAsync()
|
{
|
await UniTask.Delay(300, cancellationToken: this.GetCancellationTokenOnDestroy());
|
|
if (this != null)
|
{
|
UIManager.Instance.CloseWindow(this);
|
}
|
}
|
|
/// <summary>
|
/// 显示战斗加载界面并返回进度回报器。
|
/// 用法: var progress = await BattleLoadingWin.ShowAsync();
|
/// </summary>
|
public static async UniTask<BattleLoadingWin> ShowAsync()
|
{
|
var win = await UIManager.Instance.OpenWindowAsync("BattleLoadingWin") as BattleLoadingWin;
|
return win;
|
}
|
|
/// <summary>
|
/// IProgress 适配器实现。
|
/// </summary>
|
private class BattleLoadingProgress : IProgress<float>
|
{
|
private readonly BattleLoadingWin _win;
|
|
public BattleLoadingProgress(BattleLoadingWin win)
|
{
|
_win = win;
|
}
|
|
public void Report(float value)
|
{
|
if (_win != null)
|
{
|
_win.SetProgress(value);
|
}
|
}
|
}
|
}
|