using System;
|
using System.Collections;
|
using System.Collections.Generic;
|
using Spine.Unity;
|
using UnityEngine;
|
using Spine;
|
using UnityEngine.UI;
|
using Cysharp.Threading.Tasks;
|
|
//UI特效播放器,spine特效直接加载无需提前做预制体
|
//UI特效大部分情况不会改变特效,无需销毁
|
public class UIEffectPlayer : EffectPlayer
|
{
|
[Header("是否循环播放spine特效")]
|
public bool isPlaySpineLoop = false;
|
|
[Header("是否在显示时播放")]
|
public bool isPlayOnEnable = false;
|
|
[Header("延迟播放(毫秒)")]
|
public int playDelayTime = 0;
|
|
int playSpineAnimIndex = -1; //播放spine特效动画索引,
|
|
|
|
protected override void OnEnable()
|
{
|
playSpineAnimIndex = -1;
|
if (isPlayOnEnable)
|
{
|
PlayAsync(false).Forget();
|
}
|
else if (spineComp != null)
|
{
|
if (!isPlaying)
|
{
|
//隐藏,会有静态显示问题
|
spineComp.enabled = false;
|
}
|
}
|
}
|
|
public override void Play(bool showLog = true)
|
{
|
isPlaying = true;
|
if (!isInit)
|
{
|
InitComponent(showLog);
|
//effeid 为0也初始化成功,避免重复处理,在变更effectid时会重新初始化
|
isInit = true;
|
}
|
else
|
{
|
//避免重复创建
|
if (!this.gameObject.activeSelf)
|
{
|
this.gameObject.SetActive(true);
|
}
|
//防范effeid 为0
|
if (effectConfig != null && effectConfig.isSpine != 0)
|
{
|
PlayerTheSpineAnim();
|
}
|
return;
|
}
|
|
if (EffectMgr.IsNotShowBySetting(effectId))
|
{
|
return;
|
}
|
|
if (null != effectTarget)
|
{
|
if (pool != null)
|
pool.Release(effectTarget);
|
effectTarget = null;
|
}
|
|
if (!this.gameObject.activeSelf)
|
{
|
this.gameObject.SetActive(true);
|
}
|
|
// 加载spine特效资源
|
if (effectConfig.isSpine != 0)
|
{
|
PlaySpineEffect();
|
}
|
else
|
{
|
PlayerEffect(false);
|
}
|
SoundPlayer.Instance.PlayUIAudio(effectConfig.audio);
|
}
|
|
|
protected override void PlaySpineEffect()
|
{
|
if (spineComp == null)
|
{
|
spineComp = gameObject.AddMissingComponent<SkeletonGraphic>();
|
}
|
|
if (spineComp.skeletonDataAsset == null)
|
{
|
//LoadAsset 已经有缓存SkeletonDataAsset
|
spineComp.skeletonDataAsset = ResManager.Instance.LoadAsset<SkeletonDataAsset>("UIEffect/" + effectConfig.packageName, effectConfig.fxName);
|
spineComp.raycastTarget = false;
|
spineComp.Initialize(true);
|
|
// 检查动画是否有相加模式
|
bool hasAdditiveBlend = CheckForAdditiveBlend(spineComp.Skeleton);
|
if (hasAdditiveBlend)
|
{
|
spineComp.material = ResManager.Instance.LoadAsset<Material>("UIEffect/" + effectConfig.packageName, effectConfig.fxName.Split('_')[0] + "_Material-Additive");
|
}
|
else
|
{
|
spineComp.material = null;
|
}
|
|
spineAnimationState = spineComp.AnimationState;
|
spineAnimationState.Data.DefaultMix = 0f;
|
spineAnimationState.Complete -= OnSpineAnimationComplete;
|
spineAnimationState.Complete += OnSpineAnimationComplete;
|
}
|
|
spineComp.enabled = true;
|
PlayerTheSpineAnim();
|
}
|
|
private bool CheckForAdditiveBlend(Spine.Skeleton skeleton)
|
{
|
// 遍历所有插槽,检查是否有相加模式
|
foreach (var slot in skeleton.Slots)
|
{
|
if (slot.Data.BlendMode == Spine.BlendMode.Additive)
|
{
|
return true;
|
}
|
}
|
return false;
|
}
|
|
public void Play(int index, bool showLog = true)
|
{
|
playSpineAnimIndex = index;
|
PlayAsync(showLog).Forget();
|
}
|
|
async UniTask PlayAsync(bool showLog = true)
|
{
|
await UniTask.Delay(playDelayTime);
|
Play(showLog);
|
}
|
|
// 播放指定动画
|
void PlayerTheSpineAnim()
|
{
|
spineComp.enabled = true;
|
var skeletonData = spineComp.Skeleton.Data;
|
if (skeletonData.Animations.Count > 0)
|
{
|
string defaultAnimationName = skeletonData.Animations.Items[playSpineAnimIndex == -1 ? effectConfig.animIndex : playSpineAnimIndex].Name;
|
spineAnimationState.SetAnimation(0, defaultAnimationName, isPlaySpineLoop);
|
}
|
else
|
{
|
Debug.LogError("Spine 数据中没有找到任何动画!" + effectConfig.id);
|
}
|
}
|
|
|
|
//单次播放完毕就会触发,即使是循环
|
protected override void OnSpineAnimationComplete(Spine.TrackEntry trackEntry)
|
{
|
if (!isPlaySpineLoop)
|
{
|
spineComp.enabled = false;
|
isPlaying = false;
|
if (isReleaseImmediately)
|
{
|
Stop();
|
}
|
else
|
{
|
onComplete?.Invoke();
|
}
|
}
|
}
|
|
|
|
// 创建后的特效会自动隐藏 需要手动调用Play才能播放
|
public static UIEffectPlayer CreateEffect(int effectId, Transform parent, bool createNewChild = false)
|
{
|
UIEffectPlayer effectPlayer = null;
|
|
if (createNewChild)
|
{
|
GameObject newGo = new GameObject("EffectPlayer_" + effectId);
|
newGo.transform.SetParent(parent, false);
|
effectPlayer = newGo.AddComponent<UIEffectPlayer>();
|
}
|
else
|
{
|
effectPlayer = parent.AddMissingComponent<UIEffectPlayer>();
|
effectPlayer.effectId = effectId;
|
}
|
effectPlayer.SetActive(true);
|
return effectPlayer;
|
}
|
|
|
}
|