Files
5.24BuYu/Assets/MyGame/aa/UI/DefaultPanel/GongXiHuoDe/HuoDe.cs
T
2026-10-12 00:37:28 +08:00

137 lines
4.5 KiB
C#

using Spine;
using Spine.Unity;
using System;
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;
public class HuoDe : MonoBehaviour
{
public Button btn_Close;
public BackPackPropItem backPackPropItemPrefab;
public Transform backPackPropItemParent;
[Header("Spine 动画(固定配置)")]
[Tooltip("Spine 动画组件,留空则自动获取")]
public SkeletonGraphic skeletonGraphic;
[Tooltip("出现动画(播放一次)")]
public string appear;
[Tooltip("待机动画(循环播放)")]
public string loop;
[Tooltip("离开动画(关闭时播放一次再销毁)")]
public string leave;
public Action action;
private bool _closed;
[Header("时序(秒)")]
[Tooltip("出现动画播放多久后再展示道具")]
float showPropsDelay = 0.3f;
[Tooltip("离开动画播放多久后直接销毁(不等播完)")]
float destroyDelay = 0.3f;
private void Awake()
{
if (skeletonGraphic == null)
skeletonGraphic = GetComponent<SkeletonGraphic>();
UIClickSound.AttachToAll(gameObject); // ⭐ 弹窗是独立预制体(非 UIBase 面板),这里手动补按钮点击音效
if (btn_Close != null)
btn_Close.onClick.AddListener(Close);
}
/// <summary>
/// 按奖励数据列表克隆预制体并初始化,并播放出现动画→待机循环。
/// 道具在出现动画播放 showPropsDelay 秒后才显示,避免 spine 停滞。
/// </summary>
/// <param name="dataList">奖励道具数据列表</param>
/// <param name="onCloseAction">关闭面板时回调(处理特殊情况)</param>
public void Init(List<BackPackPropItemData> dataList, Action onCloseAction = null)
{
action = onCloseAction;
// 清空旧列表
if (backPackPropItemParent != null)
{
for (int i = backPackPropItemParent.childCount - 1; i >= 0; i--)
Destroy(backPackPropItemParent.GetChild(i).gameObject);
}
// 先隐藏父节点,等出现动画播 showPropsDelay 秒后再克隆并显示
if (backPackPropItemParent != null)
backPackPropItemParent.gameObject.SetActive(false);
PlayAppearThenLoop();
StartCoroutine(IEShowPropsAfterDelay(dataList));
}
private IEnumerator IEShowPropsAfterDelay(List<BackPackPropItemData> dataList)
{
yield return new WaitForSeconds(showPropsDelay);
if (this == null) yield break;
if (dataList != null && backPackPropItemPrefab != null && backPackPropItemParent != null)
{
foreach (var data in dataList)
{
if (data == null) continue;
var obj = Instantiate(backPackPropItemPrefab.gameObject, backPackPropItemParent);
var item = obj.GetComponent<BackPackPropItem>();
if (item == null) continue;
item.Init(data);
}
}
if (backPackPropItemParent != null)
backPackPropItemParent.gameObject.SetActive(true);
}
/// <summary>播放出现动画(一次),播完自动切到待机(循环)</summary>
private void PlayAppearThenLoop()
{
if (skeletonGraphic == null) return;
var state = skeletonGraphic.AnimationState;
if (state == null) return;
state.ClearTrack(0);
if (!string.IsNullOrEmpty(appear))
{
state.SetAnimation(0, appear, false);
if (!string.IsNullOrEmpty(loop))
state.AddAnimation(0, loop, true, 0f);
}
else if (!string.IsNullOrEmpty(loop))
{
state.SetAnimation(0, loop, true);
}
}
/// <summary>
/// 关闭面板(手动点击或自动超时都会调用,重复调用安全)。
/// 播放 leave 动画,destroyDelay 秒后直接销毁,不等动画播完。
/// </summary>
public void Close()
{
if (_closed) return;
_closed = true;
action?.Invoke();
if (skeletonGraphic != null && !string.IsNullOrEmpty(leave))
{
var state = skeletonGraphic.AnimationState;
if (state != null)
state.SetAnimation(0, leave, false);
}
StartCoroutine(IEDestroyAfterDelay());
}
private IEnumerator IEDestroyAfterDelay()
{
yield return new WaitForSeconds(destroyDelay);
if (this != null && gameObject != null)
Destroy(gameObject);
}
}