using System; using UnityEngine; public class PlayerStateMachine : MonoBehaviour { private Animator _anim; public PlayerState CurrentState { get; private set; } = PlayerState.Idle; public Action OnStateChanged; // 상태가 변했을 때 다른 컴포넌트들이 알 수 있도록 이벤트 제공 (함수 포인터 활용) public bool IsGrounded { get; set; } //상태 머신이기 때문에 계산은 여기서 안함 (플레이어가 갱신할 수 있도록 set 허용) public bool IsRunInputPressed { get; set; } //달리기키가 눌린 상태인가 public bool IsPossibleCharge { get; set; } //현재 차지 가능한 상태인가 private void Awake() { _anim = GetComponent(); } public void ChangeState(PlayerState newState) { if (CurrentState == newState) return; // 상태 전환 규칙 (예: 죽었는데 공격 상태로 갈 수 없음) if (CurrentState == PlayerState.Dead) return; CurrentState = newState; _anim.SetInteger("playerState", (int)newState); OnStateChanged?.Invoke(newState); //Debug.Log($"State Switched to: {newState}"); } #region 상태확인용 헬퍼함수들 //지상 이동이 가능한가? public bool CanMove() => IsGrounded && (CurrentState == PlayerState.Idle || CurrentState == PlayerState.Walk || CurrentState == PlayerState.Run); //점프가 가능한 상태인가? public bool CanJump() => IsGrounded && (CurrentState == PlayerState.Idle || CurrentState == PlayerState.Walk || CurrentState == PlayerState.Run); //대쉬가 가능한 상태인가? public bool CanDodge() { // 이미 구르는중 if (CurrentState == PlayerState.Dodge) return false; // 공중대쉬 제한 // if (!IsGrounded) return false; // 피격 상태이거나 죽었을 때 안 되게 if (CurrentState == PlayerState.Hit || CurrentState == PlayerState.Dead) return false; // 스태미나 시스템이 있다면 체크 // if (CurrentStamina < DodgeCost) return false; return true; } //공중에서 조작 가능한 상태인가? public bool CanControlInAir() => !IsGrounded && (CurrentState == PlayerState.Jump || CurrentState == PlayerState.Fall); //공격이 가능한 상태인가? public bool CanAttack() { //이미 공격 중이거나 차징 중이면 공격 불가 (연속기가 있다면 바뀔수 있음) if (CurrentState == PlayerState.Attack || CurrentState == PlayerState.Charge) return false; //피격(Hit) 중이거나 죽었다면(Dead) 공격 불가 if (CurrentState == PlayerState.Hit || CurrentState == PlayerState.Dead) return false; // (Idle, Walk, Run, Jump, Fall 상태에서 공격 가능) return true; } #endregion }