115 lines
3.4 KiB
C#
115 lines
3.4 KiB
C#
using System;
|
|
using System.Collections;
|
|
using Sirenix.OdinInspector;
|
|
using Spine;
|
|
using Spine.Unity;
|
|
using UnityEngine;
|
|
using AnimationState = Spine.AnimationState;
|
|
|
|
namespace BlueWater.Players
|
|
{
|
|
public class SpineController : MonoBehaviour
|
|
{
|
|
// Variables
|
|
#region Variables
|
|
// Components
|
|
[SerializeField]
|
|
private SkeletonAnimation _skeletonAnimation;
|
|
private AnimationState _animationState;
|
|
|
|
// Variables
|
|
[SerializeField]
|
|
private string _initialSkinName = "default";
|
|
|
|
#endregion
|
|
|
|
// Unity events
|
|
#region Unity events
|
|
|
|
private void Awake()
|
|
{
|
|
InitializeComponents();
|
|
}
|
|
|
|
#endregion
|
|
|
|
// Initialize methods
|
|
#region Initialize methods
|
|
|
|
[Button("셋팅 초기화")]
|
|
public virtual void InitializeComponents()
|
|
{
|
|
_skeletonAnimation = transform.GetComponentInChildren<SkeletonAnimation>();
|
|
_animationState = _skeletonAnimation.AnimationState;
|
|
SetSkin(_initialSkinName);
|
|
}
|
|
|
|
#endregion
|
|
|
|
// Methods
|
|
#region Methods
|
|
|
|
/// <param name="animationName">스파인 애니메이션 이름</param>
|
|
/// <param name="isLoopActive">반복 여부</param>
|
|
/// <param name="speed">애니메이션 속도 양수값</param>
|
|
/// <param name="isReverse">true인 경우 자동으로 speed에 음수값을 넣음</param>
|
|
/// <returns></returns>
|
|
public TrackEntry PlayAnimation(string animationName, bool isLoopActive, float speed = 1f, bool isReverse = false)
|
|
{
|
|
if (!_skeletonAnimation || _animationState == null) return null;
|
|
|
|
if (string.IsNullOrEmpty(animationName))
|
|
{
|
|
Debug.LogError($"{animationName}의 애니메이션은 존재하지 않습니다.");
|
|
return null;
|
|
}
|
|
|
|
_animationState.TimeScale = isReverse ? -Mathf.Abs(speed) : Mathf.Abs(speed);
|
|
var trackEntry = _animationState.SetAnimation(0, animationName, isLoopActive);
|
|
|
|
if (isReverse)
|
|
{
|
|
trackEntry.TrackTime = trackEntry.AnimationEnd;
|
|
}
|
|
|
|
return trackEntry;
|
|
}
|
|
|
|
public void SetSkin(string skinName)
|
|
{
|
|
if (_skeletonAnimation == null && _animationState == null) return;
|
|
|
|
if (string.IsNullOrEmpty(skinName))
|
|
{
|
|
Debug.LogError($"{skinName}의 스킨 이름은 존재하지 않습니다.");
|
|
return;
|
|
}
|
|
|
|
_skeletonAnimation.Skeleton.SetSkin(skinName);
|
|
_skeletonAnimation.Skeleton.SetSlotsToSetupPose();
|
|
_animationState.Apply(_skeletonAnimation.Skeleton);
|
|
}
|
|
|
|
public async Awaitable WaitForAnimationCompletion(TrackEntry trackEntry, bool isReverse = false)
|
|
{
|
|
if (isReverse)
|
|
{
|
|
await AwaitUntil(() => trackEntry.TrackTime <= 0);
|
|
}
|
|
else
|
|
{
|
|
await AwaitUntil(() => trackEntry.IsComplete);
|
|
}
|
|
}
|
|
|
|
public async Awaitable AwaitUntil(Func<bool> condition)
|
|
{
|
|
while (!condition())
|
|
{
|
|
await Awaitable.NextFrameAsync();
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
} |