| using UnityEngine; | 
| using System.Collections; | 
| using System.Collections.Generic; | 
| using UnityEngine.UI; | 
| using DG.Tweening; | 
| using Cysharp.Threading.Tasks; | 
|   | 
| public class MarqueeWin : UIBase | 
| { | 
|     // 组件引用 | 
|     [SerializeField] RectTransform m_ContainerMarquee; | 
|     [SerializeField] RichText marqueeText; | 
|     [SerializeField] RectTransform marqueeBg; | 
|     [SerializeField] TweenCurve tweenCurve; | 
|     [SerializeField] UIEffectPlayer m_Effect; | 
|   | 
|     Vector3 fromPos; | 
|     Vector3 toPos; | 
|     float m_Time; | 
|     float duration; | 
|     int presentCnt = 0; | 
|     int loopCnt = 1; | 
|   | 
|     [SerializeField] | 
|     float speed = 5.0f; | 
|   | 
|     Coroutine cacheCoroutine = null; | 
|   | 
|     // 生命周期 | 
|     protected override void Awake() | 
|     { | 
|         base.Awake(); | 
|         // 初始化组件引用 | 
|         fromPos = marqueeText.rectTransform.localPosition; | 
|     } | 
|   | 
|     protected override void Start() | 
|     { | 
|         base.Start(); | 
|         // 初始化数据 | 
|     } | 
|   | 
|     protected override void OnPreOpen() | 
|     { | 
|         // 子类可以重写此方法进行额外的预打开操作 | 
|         base.OnPreOpen(); | 
|   | 
|         m_Time = 0; | 
|         ServerTipDetails.OnTweening = false; | 
|         presentCnt = 0; | 
|         m_ContainerMarquee.SetActive(false); | 
|         if (cacheCoroutine != null) | 
|         { | 
|             StopCoroutine(cacheCoroutine); | 
|             cacheCoroutine = null; | 
|         } | 
|     } | 
|   | 
|     // UI事件 | 
|     protected override void OnOpen() | 
|     { | 
|         base.OnOpen(); | 
|         // 窗口打开时的逻辑 | 
|         if (m_Effect.effectId > 0) | 
|             m_Effect.Play(); | 
|         cacheCoroutine = StartCoroutine(Co_StartTween()); | 
|     } | 
|   | 
|     protected override void OnClose() | 
|     { | 
|         base.OnClose(); | 
|         // 窗口关闭时的逻辑 | 
|     } | 
|   | 
|     IEnumerator Co_StartTween() | 
|     { | 
|         yield return new WaitForSeconds(5f); | 
|         m_ContainerMarquee.SetActive(true); | 
|         BeginMarquee(); | 
|     } | 
|   | 
|     void BeginMarquee() | 
|     { | 
|         if (presentCnt == 0) | 
|         { | 
|             var _hint = ServerTipDetails.RequireMarquee(); | 
|             if (_hint != null) | 
|             { | 
|                 presentCnt = 0; | 
|                 marqueeText.SetExtenalData(_hint.extentionData); | 
|                 marqueeText.text = _hint.message; | 
|             } | 
|             else | 
|             { | 
|                 CloseWindow(); | 
|                 return; | 
|             } | 
|         } | 
|         presentCnt++; | 
|         marqueeText.rectTransform.localPosition = fromPos; | 
|         toPos = fromPos; | 
|         float width = marqueeText.preferredWidth; | 
|         toPos.x = fromPos.x - marqueeBg.rect.width - width; | 
|         duration = (width + marqueeBg.rect.width) / speed; | 
|         ServerTipDetails.OnTweening = true; | 
|     } | 
|   | 
|     void OnTweenComp() | 
|     { | 
|         m_Time = 0; | 
|         ServerTipDetails.OnTweening = false; | 
|         if (presentCnt >= loopCnt) | 
|         { | 
|             presentCnt = 0; | 
|         } | 
|         BeginMarquee(); | 
|     } | 
|   | 
|     protected void LateUpdate() | 
|     { | 
|         if (ServerTipDetails.OnTweening) | 
|         { | 
|             m_Time += Time.deltaTime; | 
|             if (m_Time <= duration) | 
|             { | 
|                 float progress = tweenCurve.Evaluate(m_Time / duration); | 
|                 marqueeText.rectTransform.localPosition = Vector3.Lerp(fromPos, toPos, progress); | 
|             } | 
|             else | 
|             { | 
|                 OnTweenComp(); | 
|             } | 
|         } | 
|     } | 
| } |