OldBlueWater/BlueWater/Assets/02.Scripts/Character/CombatPlayer2D/CombatAnimator.cs
NTG f1d0c6d371 Closes #244, #254 CombatPlayer 개선, 하트 시스템 추가
+ CombatPlayer 기능별 분리
+ Combat, CombatUi 전용 input action map 추가
+ 스킬 시스템 로직 수정
+ 전투플레이어 스킬(검의 왈츠) 로직 변경
2024-05-08 00:37:33 +09:00

199 lines
7.7 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
public enum CombatPlayerAnimatorParameter
{
X_DIRECTION,
Z_DIRECTION,
IS_MOVING,
IS_DASHING,
IS_READY_MAIN_SKILL,
IS_ACTIVATE_MAIN_SKILL,
COMBO_ATTACK_COUNT
}
public enum CombatPlayerAnimationName
{
DASH_STATE,
COMBO_ATTACK1,
COMBO_ATTACK2,
READY_TO_MAIN_SKILL,
MAIN_SKILL
}
public class CombatAnimator : MonoBehaviour, IAnimationStateController
{
// Components
private Animator anim;
// Dictionaries
private Dictionary<CombatPlayerAnimatorParameter, int> animationParameterHashDictionary = new();
private Dictionary<CombatPlayerAnimationName, int> animationNameHashDictionary = new();
// Parameter hashes
private static readonly int XDirectionHash = Animator.StringToHash("xDirection");
private static readonly int ZDirectionHash = Animator.StringToHash("zDirection");
private static readonly int IsMovingHash = Animator.StringToHash("isMoving");
private static readonly int IsDashingHash = Animator.StringToHash("isDashing");
private static readonly int IsReadyMainSkillHash = Animator.StringToHash("isReadyMainSkill");
private static readonly int IsActivateMainSkillHash = Animator.StringToHash("isActivateMainSkill");
private static readonly int ComboAttackCount = Animator.StringToHash("ComboAttackCount");
// Animation name hashes
private static readonly int DashStateHash = Animator.StringToHash("DashState");
private static readonly int ComboAttack1Hash = Animator.StringToHash("ComboAttack1");
private static readonly int ComboAttack2Hash = Animator.StringToHash("ComboAttack2");
private static readonly int ReadyToMainSkillHash = Animator.StringToHash("ReadyToMainSkill");
private static readonly int MainSkillHash = Animator.StringToHash("MainSkill");
// Unity events
private void Awake()
{
InitDictionary();
}
// Init
public void InitComponent(Animator animator)
{
anim = animator;
}
private void InitDictionary()
{
animationParameterHashDictionary = new Dictionary<CombatPlayerAnimatorParameter, int>(Enum.GetValues(typeof(CombatPlayerAnimatorParameter)).Length)
{
{ CombatPlayerAnimatorParameter.X_DIRECTION, XDirectionHash },
{ CombatPlayerAnimatorParameter.Z_DIRECTION, ZDirectionHash },
{ CombatPlayerAnimatorParameter.IS_MOVING, IsMovingHash },
{ CombatPlayerAnimatorParameter.IS_DASHING, IsDashingHash },
{ CombatPlayerAnimatorParameter.IS_READY_MAIN_SKILL, IsReadyMainSkillHash },
{ CombatPlayerAnimatorParameter.IS_ACTIVATE_MAIN_SKILL, IsActivateMainSkillHash },
{ CombatPlayerAnimatorParameter.COMBO_ATTACK_COUNT, ComboAttackCount }
};
animationNameHashDictionary = new Dictionary<CombatPlayerAnimationName, int>(Enum.GetValues(typeof(CombatPlayerAnimationName)).Length)
{
{ CombatPlayerAnimationName.DASH_STATE, DashStateHash },
{ CombatPlayerAnimationName.COMBO_ATTACK1, ComboAttack1Hash },
{ CombatPlayerAnimationName.COMBO_ATTACK2, ComboAttack2Hash },
{ CombatPlayerAnimationName.READY_TO_MAIN_SKILL, ReadyToMainSkillHash },
{ CombatPlayerAnimationName.MAIN_SKILL, MainSkillHash }
};
}
// Methods
public void SetAnimationParameter<T>(T parameter, bool value)
{
if (parameter is CombatPlayerAnimatorParameter enumParameter)
{
anim.SetBool(animationParameterHashDictionary[enumParameter], value);
}
else
{
throw new ArgumentException("Invalid parameter type for SetAnimationParameter");
}
}
public void SetAnimationParameter<T>(T parameter, int value)
{
if (parameter is CombatPlayerAnimatorParameter enumParameter)
{
anim.SetInteger(animationParameterHashDictionary[enumParameter], value);
}
else
{
throw new ArgumentException("Invalid parameter type for SetAnimationParameter");
}
}
public void SetAnimationParameter<T>(T parameter, float value)
{
if (parameter is CombatPlayerAnimatorParameter enumParameter)
{
anim.SetFloat(animationParameterHashDictionary[enumParameter], value);
}
else
{
throw new ArgumentException("Invalid parameter type for SetAnimationParameter");
}
}
public void SetAnimationTrigger<T>(T parameter)
{
if (parameter is CombatPlayerAnimatorParameter enumParameter)
{
anim.SetTrigger(animationParameterHashDictionary[enumParameter]);
}
else
{
throw new ArgumentException("Invalid parameter type for SetAnimationParameter");
}
}
public void ResetAnimationSpeed()
{
anim.speed = 1f;
}
public bool IsComparingCurrentAnimation(string animationName, int animatorLayer = 0)
{
return anim.GetCurrentAnimatorStateInfo(animatorLayer).IsName(animationName);
}
public bool IsComparingCurrentAnimation<T>(T animationName, int animatorLayer = 0)
{
if (animationName is CombatPlayerAnimationName enumAnimationName)
{
return anim.GetCurrentAnimatorStateInfo(animatorLayer).shortNameHash == animationNameHashDictionary[enumAnimationName];
}
throw new ArgumentException("Invalid parameter type for SetAnimationParameter");
}
public IEnumerator WaitForAnimationToRun(string animationName, Action<bool> onSuccess, float timeout = 0.2f)
{
var elapsedTime = 0f;
while (!IsComparingCurrentAnimation(animationName))
{
elapsedTime += Time.deltaTime;
yield return null;
if (elapsedTime <= timeout) continue;
print("Timeout waiting for animation state: " + animationName);
onSuccess?.Invoke(false);
}
onSuccess?.Invoke(true);
}
public IEnumerator WaitForAnimationToRun<T>(T animationName, Action<bool> onSuccess, float timeout = 0.2f)
{
var elapsedTime = 0f;
while (!IsComparingCurrentAnimation(animationName))
{
elapsedTime += Time.deltaTime;
yield return null;
if (elapsedTime <= timeout) continue;
print("Timeout waiting for animation state: " + animationName);
onSuccess?.Invoke(false);
}
onSuccess?.Invoke(true);
}
public void SetCurrentAnimationSpeed(float targetDuration, int animatorLayer = 0)
{
var animationLength = anim.GetCurrentAnimatorStateInfo(animatorLayer).length;
anim.speed = animationLength / targetDuration;
}
public float GetCurrentAnimationNormalizedTime(int animatorLayer = 0)
{
return anim.GetCurrentAnimatorStateInfo(animatorLayer).normalizedTime;
}
}
}