Files
aibis-dream/Assets/Scripts/UI/Panel/PlayToolPanel.cs
T

304 lines
9.8 KiB
C#

using System;
using System.Collections;
using AibisDream.Framework;
using AibisDream.Kit;
using DG.Tweening;
using RainbowArt.CleanFlatUI;
using UnityEngine;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.UI;
namespace AibisDream.UI
{
/// <summary>
/// 主要用来放置淡入淡出,图片展示等演出工具
/// </summary>
public class PlayToolPanel : MonoBehaviour, IUIPanel
{
public bool IsOpen => gameObject.activeSelf;
public bool IsCloseable => false;
[Header("Obj尺寸参数")] public float objWidth;
public float objHeight;
/// <summary>Addressable Key 模板,与 Obj 精灵 Address 一致。</summary>
private const string ObjSpritePath = "Sprite/Obj/{0}.png";
#region 索引
private Image _fadeImage;
private GameObject _showObjPanel;
private Image _showObjImage;
private Image _fullScreenImage;
private Image _redFlash;
private ModalWindowProgressBar _window;
private ModalWindow _warningWindow;
private SignBoard _signBoard;
private TimeTurner _timeTurner;
private int _timeFlowsVersion;
#endregion
private void Awake()
{
InitRefs();
EnumEventSystem.Global.Register(GameLoopEnum.GameQuit, HideAll);
}
private void InitRefs()
{
_fadeImage = transform.Find("Fade Image").GetComponent<Image>();
_showObjPanel = transform.Find("Show Obj").gameObject;
_showObjImage = _showObjPanel.transform.Find("Obj").GetComponent<Image>();
_fullScreenImage = transform.Find("Full Screen Image").GetComponent<Image>();
_window = transform.Find("进度条窗口").GetComponent<ModalWindowProgressBar>();
_redFlash = transform.Find("Red Flash").GetComponent<Image>();
_warningWindow = transform.Find("警告窗口").GetComponent<ModalWindow>();
_signBoard = transform.GetComponentInChildren<SignBoard>();
_timeTurner = transform.GetComponentInChildren<TimeTurner>();
}
private static string NormalizeObjPicName(string picName)
{
if (string.IsNullOrEmpty(picName)) return picName;
return picName.EndsWith(".png", StringComparison.OrdinalIgnoreCase)
? picName.Substring(0, picName.Length - 4)
: picName;
}
public IEnumerator FadeInAsync(float duration = 1)
{
return _fadeImage.FadeInAsync(duration);
}
public IEnumerator FadeOutAsync(float duration = 1)
{
return _fadeImage.FadeOutAsync(duration);
}
public void FadeInSync(float duration = 1)
{
StartCoroutine(FadeInAsync(duration));
}
public void FadeOutSync(float duration = 1)
{
StartCoroutine(FadeOutAsync(duration));
}
/// <summary>
/// 捕获遮罩终态:黑屏盖住(FadeIn 完成) vs 画面可见(FadeOut 完成 / HideAll)。
/// 与 <see cref="FadeKit"/> 一致——终态以 <c>gameObject.activeSelf</c> 为准(FadeOut 结束会 SetActive(false))。
/// </summary>
public bool CaptureFadeScreenCovered()
{
if (_fadeImage == null) return false;
return _fadeImage.gameObject.activeSelf;
}
/// <summary>
/// 按快照终态还原遮罩(同步设置 active 与颜色,与 <see cref="FadeKit"/> 终态一致)。
/// </summary>
public void ApplyFadeScreenCovered(bool isCovered)
{
if (_fadeImage == null) return;
_fadeImage.DOKill();
if (isCovered)
{
_fadeImage.gameObject.SetActive(true);
_fadeImage.color = Color.white;
}
else
{
_fadeImage.color = Color.clear;
_fadeImage.gameObject.SetActive(false);
}
}
/// <summary>
/// 显示物体
/// </summary>
/// <returns>协程</returns>
public IEnumerator ShowObj(string picName)
{
_showObjPanel.gameObject.SetActive(true);
var key = string.Format(ObjSpritePath, NormalizeObjPicName(picName));
var handle = ResourceSystem.LoadAsync<Sprite>(key);
yield return handle;
if (handle.Status != AsyncOperationStatus.Succeeded || handle.Result == null)
{
Debug.LogError($"[PlayToolPanel] Failed to load sprite: {key}");
yield break;
}
var newSprite = handle.Result;
// 获取图片的长宽比
var imageAspect = (float)newSprite.texture.width / newSprite.texture.height;
// 计算新的尺寸
if (imageAspect > 1) // 宽图
{
var newHeight = objWidth / imageAspect;
_showObjImage.rectTransform.sizeDelta = new Vector2(objWidth, newHeight);
}
else // 高图
{
var newWidth = objHeight * imageAspect;
_showObjImage.rectTransform.sizeDelta = new Vector2(newWidth, objHeight);
}
// 淡入
_showObjImage.sprite = newSprite;
yield return _showObjImage.FadeInAsync(1);
}
public IEnumerator HideObj()
{
yield return _showObjImage.FadeOutAsync(1);
_showObjPanel.SetActive(false);
}
public IEnumerator ShowFullScreen(string picName)
{
var key = string.Format(ObjSpritePath, NormalizeObjPicName(picName));
var handle = ResourceSystem.LoadAsync<Sprite>(key);
yield return handle;
if (handle.Status != AsyncOperationStatus.Succeeded || handle.Result == null)
{
Debug.LogError($"[PlayToolPanel] Failed to load sprite: {key}");
yield break;
}
_fullScreenImage.sprite = handle.Result;
// 淡入
yield return _fullScreenImage.FadeInAsync(1);
}
public IEnumerator HideFullScreen()
{
return _fullScreenImage.FadeOutAsync(1);
}
public IEnumerator OpenProgressWindow(string title, string description, float duration)
{
AudioManager.Instance.PlaySfx("event:/Scriptal/Ui");
_window.TitleValue = title;
_window.DescriptionValue = description;
float currentProgress = 0;
DOTween.To(
() => currentProgress,
value =>
{
currentProgress = value;
_window.SetProgress(currentProgress); // 更新进度
},
100,
duration
);
_window.ShowModalWindow();
// 获取 moveText 的 RectTransform
RectTransform moveTextRect =
_window.transform.Find("View/mask/moveText")?.GetComponent<RectTransform>();
if (moveTextRect != null)
{
moveTextRect.DOAnchorPosY(0f, duration).SetEase(Ease.Linear);
}
// 等待用户确认
yield return new WaitUntil(() => currentProgress >= 100);
_window.HideModalWindow();
moveTextRect.DOAnchorPosY(1326f, 0.1f).SetEase(Ease.Linear);
}
// 红色闪烁效果
public IEnumerator FlashRed(float duration)
{
_redFlash.gameObject.SetActive(true);
yield return _redFlash.FadeInAsync(duration / 2);
yield return _redFlash.FadeOutAsync(duration / 2);
_redFlash.gameObject.SetActive(false);
}
public void ShowSignBoard()
{
_signBoard.ShowSignBoard();
}
public void EnableSignBoard()
{
_signBoard.EnableSignBoard();
}
public void CloseSignBoard()
{
_signBoard.CloseSignBoard();
}
private void HideAll()
{
_timeFlowsVersion++;
_fadeImage.DOKill();
_fadeImage.color = Color.clear;
_fadeImage.gameObject.SetActive(false);
_fullScreenImage.FadeOut(0.1f);
_showObjImage.FadeOut(0.1f);
_showObjPanel.SetActive(false);
_timeTurner.ForceStop();
}
// ------------------------------- 时间流转 -------------------------------
public IEnumerator TimeFlowsOn(string originState, string targetState)
{
var version = ++_timeFlowsVersion;
// 黑屏淡入
yield return _fadeImage.FadeInAsync(0.5f);
if (version != _timeFlowsVersion) yield break;
// 时间流转
yield return _timeTurner.TurnTimeTo(originState, targetState);
if (version != _timeFlowsVersion) yield break;
// 黑屏淡出
yield return _fadeImage.FadeOutAsync(0.5f);
}
#region 感觉这个面板应该常驻
public void Show()
{
gameObject.SetActive(true);
}
public void Hide()
{
gameObject.SetActive(false);
}
#endregion
/// <summary>
/// 打开警告窗口
/// </summary>
/// <param name="description">警告描述文本</param>
/// <returns>等待玩家确认的协程</returns>
public IEnumerator OpenWarningWindow(string description)
{
AudioManager.Instance.PlaySfx("event:/Scriptal/Ui");
_warningWindow.DescriptionValue = description;
_warningWindow.ShowModalWindow();
// 等待玩家点击确认按钮
yield return new WaitUntil(() => !_warningWindow.gameObject.activeSelf);
}
}
}