137 lines
4.5 KiB
C#
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);
|
|
}
|
|
}
|