Files
5.24BuYu/Assets/MyGame/aa/Game/FLZY/BOSS/BJEndUI.cs
T
2026-08-09 17:57:46 +08:00

201 lines
7.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using DG.Tweening;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class BJEndUI : MonoBehaviour
{
public TextMeshProUGUI tMP_beishu;
public TextMeshProUGUI tMP_score;
public TMP_SpriteAsset goldSprite;
public TMP_SpriteAsset SilverSprite;
public Image img_BaoJiangZhong;
public bool useScoreAnim = false; // 是否启用分数递增动画
/// <summary>默认自动销毁延时(秒);not-self 在途状态会取消此计时,等 Finalize 后才重启</summary>
public float autoDestroyDelay = 5f;
[Header("Animator 状态机触发参数(not-self 流程)")]
[Tooltip("出现动画的 Trigger 参数名(ShowInProgress 入口触发)")]
public string animTrigger_Appear = "Appear";
[Tooltip("持续动画的 Trigger 参数名(ShowInProgress 出现动画完成后触发)")]
public string animTrigger_Loop = "Loop";
[Tooltip("关闭动画的 Trigger 参数名(Finalize 时触发,播完后销毁)")]
public string animTrigger_Close = "Close";
private Coroutine _destroyCo;
/// <summary>预制体自带的 Animator(出现/持续/关闭 三态由状态机控制)</summary>
private Animator _animator;
private void Awake()
{
_animator = GetComponent<Animator>();
if (autoDestroyDelay > 0)
_destroyCo = StartCoroutine(DestroyAfter(autoDestroyDelay));
}
private IEnumerator DestroyAfter(float delay)
{
yield return new WaitForSeconds(delay);
Destroy(gameObject);
}
/// <summary>取消当前自动销毁计时(用于 not-self 流程切换状态前)</summary>
public void CancelAutoDestroy()
{
if (_destroyCo != null)
{
StopCoroutine(_destroyCo);
_destroyCo = null;
}
}
/// <summary>
/// 重置销毁计时并启动新的延时销毁。
/// </summary>
public void RestartAutoDestroy(float delay)
{
CancelAutoDestroy();
if (delay > 0)
_destroyCo = StartCoroutine(DestroyAfter(delay));
}
public void Init(int beishu, long score, bool isMine = false)
{
// 自己爆奖用金色精灵,别人用银色
tMP_beishu.spriteAsset = isMine ? goldSprite : SilverSprite;
tMP_score.spriteAsset = isMine ? goldSprite : SilverSprite;
tMP_beishu.text = "<sprite=6>"+ beishu.ToString();
if (useScoreAnim)
StartCoroutine(ScoreAnim(score));
else
tMP_score.text = score.ToString();
}
/// <summary>
/// not-self 爆奖进入"爆奖中"状态:
/// 关闭 tMP_beishu,激活 img_BaoJiangZhong,取消自动销毁(一直保持,直到收到 baoJiangEnd)。
/// 由 BaoJiangNotSelfHandler.ShowInProgress 调用。
/// 注意:此状态下 BJEndUI 不会自动消失,必须等 Finalize 才会显示倍率并启动销毁计时。
/// </summary>
public void ShowInProgress(bool isMine)
{
// 取消自动销毁:在途状态一直保持,直到收到 baoJiangEnd 帧同步走 Finalize
CancelAutoDestroy();
if (tMP_beishu != null) tMP_beishu.gameObject.SetActive(false);
if (tMP_score != null) tMP_score.gameObject.SetActive(false);
if (img_BaoJiangZhong != null) img_BaoJiangZhong.gameObject.SetActive(true);
// 预先应用金/银 spriteAsset,Finalize 时不用再切换
if (tMP_beishu != null) tMP_beishu.spriteAsset = isMine ? goldSprite : SilverSprite;
if (tMP_score != null) tMP_score.spriteAsset = isMine ? goldSprite : SilverSprite;
// ⭐ 触发 Animator 状态机:Appear(出现)→ Loop(持续,直到 Finalize)
// Animator 从 Appear 状态自然过渡到 Loop,由状态机配置控制时机
if (_animator != null)
{
if (!string.IsNullOrEmpty(animTrigger_Loop))
_animator.SetTrigger(animTrigger_Loop);
}
}
/// <summary>
/// not-self 收到帧同步 baoJiangEnd 后调用:
/// 1. 激活 tMP_beishu,关闭 img_BaoJiangZhong(必须)
/// 2. 触发 Close 动画状态机,播放分数递增1秒
/// 3. 等 Close 动画播完后销毁(缩小由 Animator 控制,不由代码 DOScale)
/// </summary>
public void Finalize(int beishu, long score, bool isMine)
{
CancelAutoDestroy();
// 步骤1:切换显示(必须)
if (tMP_beishu != null) tMP_beishu.gameObject.SetActive(true);
if (tMP_score != null) tMP_score.gameObject.SetActive(true);
if (img_BaoJiangZhong != null) img_BaoJiangZhong.gameObject.SetActive(false);
// 写入倍数 + 金银精灵
if (tMP_beishu != null)
{
tMP_beishu.spriteAsset = isMine ? goldSprite : SilverSprite;
tMP_beishu.text = "<sprite=6>" + beishu.ToString();
}
if (tMP_score != null)
{
tMP_score.spriteAsset = isMine ? goldSprite : SilverSprite;
}
// 步骤2+3:ScoreAnim 1秒递增 → 触发 Close 动画 → 等动画播完销毁
_destroyCo = StartCoroutine(FinalizeSequence(score));
}
/// <summary>
/// not-self 收尾序列:
/// 1. ScoreAnim 1秒递增(或等待1秒)
/// 2. 触发 Close 动画状态机(缩小由 Animator 控制)
/// 3. 等待动画播完后销毁(Animator 关闭动画结束时机由 Exit Time 或 AnimationEvent 决定,
/// 此处用动画长度作为兜底等待)
/// </summary>
private IEnumerator FinalizeSequence(long score)
{
// 等1秒(无论 useScoreAnim 是否开启,都要等1秒再触发 Close)
if (useScoreAnim && tMP_score != null)
{
yield return StartCoroutine(ScoreAnim(score));
}
else
{
if (tMP_score != null) tMP_score.text = score.ToString();
yield return new WaitForSeconds(1f);
}
// 触发 Close 动画状态机(缩小/淡出由 Animator 控制)
if (_animator != null && !string.IsNullOrEmpty(animTrigger_Close))
{
_animator.SetTrigger(animTrigger_Close);
// 等 Close 动画播完:优先用 AnimatorStateInfo.length,回退固定 0.5 秒
// 注意:Trigger 触发后需要等一帧让 Animator 切换状态,再读取 length
yield return null;
var stateInfo = _animator.GetCurrentAnimatorStateInfo(0);
float waitTime = stateInfo.length > 0 ? stateInfo.length : 0.5f;
yield return new WaitForSeconds(waitTime);
}
else
{
// 无 Animator:回退到 DOScale 缩小
yield return transform.DOScale(Vector3.zero, 0.3f).SetEase(Ease.InBack).WaitForCompletion();
}
Destroy(gameObject);
}
private IEnumerator ScoreAnim(long target)
{
float duration = 1f;
float elapsed = 0f;
tMP_score.text = "0";
// 放大
Vector3 normalScale = tMP_score.transform.localScale;
tMP_score.transform.DOScale(normalScale * 1.3f, duration * 0.3f).SetEase(Ease.OutBack);
while (elapsed < duration)
{
elapsed += Time.deltaTime;
tMP_score.text = ((long)(target * elapsed / duration)).ToString();
yield return null;
}
tMP_score.text = target.ToString();
tMP_score.transform.DOScale(normalScale, 0.15f).SetEase(Ease.InBack);
}
}