Frame/Assets/Scripts/Spine/SpineAnimator.cs

114 lines
3.2 KiB
C#

using System;
using Cysharp.Threading.Tasks;
using Spine;
using Spine.Unity;
using UnityEngine;
namespace Game.Spine
{
public interface ISpineAnimator
{
SkeletonAnimation skeletonAnimation { get; }
Action<TrackEntry> complete { get; set; }
void PlayAni(string animaName, bool isLoop);
UniTask PlayAniAsync(string animaName);
UniTask PlayAniAsync(string animaName, float time);
/// <summary>
/// 从某一帧开始播放某个动画
/// </summary>
/// <param name="index"></param>
/// <param name="animaName"></param>
/// <param name="isLoop"></param>
void PlayAniFromPoint(int index, string animaName, bool isLoop);
void StopAni();
}
public class SpineAnimator : MonoBehaviour, ISpineAnimator
{
[SerializeField] private SkeletonAnimation _skeletonAnimation;
private bool _isPlaying;
public SkeletonAnimation skeletonAnimation => this._skeletonAnimation;
public Action<TrackEntry> complete { get; set; }
private void Awake()
{
if (this._skeletonAnimation == null)
throw new NullReferenceException();
complete = null;
_isPlaying = false;
}
private void Start()
{
this._skeletonAnimation.state.Complete += Finish;
this.StopAni();
}
private void OnDestroy()
{
this._skeletonAnimation.state.Complete -= Finish;
}
private void Finish(TrackEntry trackentry)
{
// Debug.Log("动画播放完成: " + trackentry.Animation.Name);
_isPlaying = false;
complete?.Invoke(trackentry);
}
public virtual void PlayAni(string animaName, bool isLoop = false)
{
_skeletonAnimation.AnimationName = animaName;
this._skeletonAnimation.loop = isLoop;
}
/// <summary>
/// 仅适用于一次性播放动画,循环动画勿用
/// </summary>
/// <param name="animaName"></param>
/// <returns></returns>
public async UniTask PlayAniAsync(string animaName)
{
_isPlaying = true;
this._skeletonAnimation.loop = false;
this._skeletonAnimation.AnimationName = animaName;
while (_isPlaying)
{
await UniTask.Yield();
}
}
/// <summary>
/// 播放某个动画多少秒
/// </summary>
/// <param name="animaName"></param>
/// <param name="time"></param>
public async UniTask PlayAniAsync(string animaName, float time)
{
this._skeletonAnimation.loop = true;
this._skeletonAnimation.AnimationName = animaName;
float f = 0;
f = time * 1000;
await UniTask.Delay((int)f);
this._skeletonAnimation.loop = false;
StopAni();
}
public void PlayAniFromPoint(int index, string animaName, bool isLoop)
{
throw new NotImplementedException();
}
public void StopAni()
{
_skeletonAnimation.AnimationName = default;
}
}
}