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 { /// /// 主要用来放置淡入淡出,图片展示等演出工具 /// public class PlayToolPanel : MonoBehaviour, IUIPanel { public bool IsOpen => gameObject.activeSelf; public bool IsCloseable => false; [Header("Obj尺寸参数")] public float objWidth; public float objHeight; /// Addressable Key 模板,与 Obj 精灵 Address 一致。 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; #endregion private void Awake() { InitRefs(); EnumEventSystem.Global.Register(GameLoopEnum.GameQuit, HideAll); } private void InitRefs() { _fadeImage = transform.Find("Fade Image").GetComponent(); _showObjPanel = transform.Find("Show Obj").gameObject; _showObjImage = _showObjPanel.transform.Find("Obj").GetComponent(); _fullScreenImage = transform.Find("Full Screen Image").GetComponent(); _window = transform.Find("进度条窗口").GetComponent(); _redFlash = transform.Find("Red Flash").GetComponent(); _warningWindow = transform.Find("警告窗口").GetComponent(); _signBoard = transform.GetComponentInChildren(); _timeTurner = transform.GetComponentInChildren(); } 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)); } /// /// 显示物体 /// /// 协程 public IEnumerator ShowObj(string picName) { _showObjPanel.gameObject.SetActive(true); var key = string.Format(ObjSpritePath, NormalizeObjPicName(picName)); var handle = ResourceSystem.LoadAsync(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(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(); 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() { _fullScreenImage.FadeOut(0.1f); _showObjImage.FadeOut(0.1f); _showObjPanel.SetActive(false); } // ------------------------------- 时间流转 ------------------------------- public IEnumerator TimeFlowsOn(string originState, string targetState) { // 黑屏淡入 yield return _fadeImage.FadeInAsync(0.5f); // 时间流转 yield return _timeTurner.TurnTimeTo(originState, targetState); // 黑屏淡出 yield return _fadeImage.FadeOutAsync(0.5f); } #region 感觉这个面板应该常驻 public void Show() { gameObject.SetActive(true); } public void Hide() { gameObject.SetActive(false); } #endregion /// /// 打开警告窗口 /// /// 警告描述文本 /// 等待玩家确认的协程 public IEnumerator OpenWarningWindow(string description) { AudioManager.Instance.PlaySfx("event:/Scriptal/Ui"); _warningWindow.DescriptionValue = description; _warningWindow.ShowModalWindow(); // 等待玩家点击确认按钮 yield return new WaitUntil(() => !_warningWindow.gameObject.activeSelf); } } }