ProjectDDD/Assets/_DDD/_Scripts/Restaurant/Character/Player/PlayerAnimation.cs

191 lines
6.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
namespace DDD.Restaurant
{
public enum PlayerTaskAnimationState
{
None = 0,
Dashing
}
public enum PlayerDefaultAnimationState
{
None = 0,
Idle = 1,
Moving = 2,
}
[RequireComponent(typeof(PlayerMovement))]
public class PlayerAnimation : CharacterAnimation
{
private IInteractor _interactor;
private IMovementState _movementState;
private PlayerTaskAnimationState _currentTaskAnimationState = PlayerTaskAnimationState.None;
private CharacterActionState _currentActionState = CharacterActionState.None;
private PlayerDefaultAnimationState _currentDefaultAnimationState = PlayerDefaultAnimationState.None;
private Dictionary<PlayerTaskAnimationState, string> _taskToAnimation = new()
{
{ PlayerTaskAnimationState.Dashing, "Dash" },
};
private Dictionary<CharacterActionState, string> _actionToAnimation = new()
{
{ CharacterActionState.CleaningTable, "Cleaning/CleaningTable" },
};
private Dictionary<PlayerDefaultAnimationState, string> _defaultToAnimation = new()
{
{ PlayerDefaultAnimationState.Idle, "Idle" },
{ PlayerDefaultAnimationState.Moving, "RunFast" },
};
protected override void Awake()
{
base.Awake();
_interactor = GetComponent<IInteractor>();
_movementState = GetComponent<IMovementState>();
}
protected override void Start()
{
base.Start();
InitializeTaskAnimations();
}
protected override void Update()
{
UpdateAnimations();
}
protected override void OnDestroy()
{
base.OnDestroy();
if (_movementState != null)
{
_movementState.OnDashing -= HandleDashingTask;
}
}
private void InitializeTaskAnimations()
{
_movementState.OnDashing += HandleDashingTask;
}
private void UpdateAnimations()
{
// 1순위: Task 애니메이션이 재생 중이면 다른 애니메이션 처리하지 않음
if (_currentTaskAnimationState != PlayerTaskAnimationState.None)
{
_currentActionState = CharacterActionState.None;
_currentDefaultAnimationState = PlayerDefaultAnimationState.None;
return;
}
// 2순위: ActionState 체크
var desiredActionState = GetDesiredActionState();
if (desiredActionState == CharacterActionState.None)
{
_currentActionState = CharacterActionState.None;
}
else
{
if (_currentActionState != desiredActionState)
{
_currentDefaultAnimationState = PlayerDefaultAnimationState.None;
_currentActionState = desiredActionState;
PlayActionAnimation(_currentActionState);
}
return;
}
// 3순위: 기본 AnimationState 처리
var desiredADefaultState = GetDesiredADefaultState();
if (_currentDefaultAnimationState != desiredADefaultState)
{
_currentDefaultAnimationState = desiredADefaultState;
PlayStateAnimation(_currentDefaultAnimationState);
}
}
private void HandleDashingTask(float duration)
{
_ = PlayTaskAnimation(PlayerTaskAnimationState.Dashing, duration);
}
private async Task PlayTaskAnimation(PlayerTaskAnimationState state, float duration = 0f)
{
_currentTaskAnimationState = state;
if (_taskToAnimation.TryGetValue(state, out string animationName))
{
if (duration > 0f)
{
_spineController.PlayAnimationDuration(animationName, false, duration);
}
else
{
_spineController.PlayAnimation(animationName, false);
}
}
await Awaitable.WaitForSecondsAsync(duration);
_currentTaskAnimationState = PlayerTaskAnimationState.None;
}
private CharacterActionState GetDesiredActionState()
{
if (_interactor.IsInteracting() == false) return CharacterActionState.None;
if (_interactor is ICharacterActionStateProvider actionStateProvider)
{
return actionStateProvider.GetCurrentActionState();
}
return CharacterActionState.None;
}
private void PlayActionAnimation(CharacterActionState actionState)
{
if (_actionToAnimation.TryGetValue(actionState, out string animationName))
{
_spineController.PlayAnimation(animationName, true);
}
}
private PlayerDefaultAnimationState GetDesiredADefaultState()
{
if (_movementState.IsMoving())
{
return PlayerDefaultAnimationState.Moving;
}
return PlayerDefaultAnimationState.Idle;
}
private void PlayStateAnimation(PlayerDefaultAnimationState state)
{
if (_defaultToAnimation.TryGetValue(state, out string animationName))
{
switch (state)
{
case PlayerDefaultAnimationState.None:
break;
case PlayerDefaultAnimationState.Idle:
case PlayerDefaultAnimationState.Moving:
_spineController.PlayAnimation(animationName, true);
break;
default:
throw new ArgumentOutOfRangeException(nameof(state), state, null);
}
}
}
}
}