using UnityEngine; public class StateMachine { private IState _state; public StateMachine(IState state) { _state = state; _state.Enter(); } public void Update() { _state.Update(); var newState = _state.CheckTransition(); // 상태가 변경되었는지 확인 (참조가 다르면) if (_state != newState) { _state.Exit(); SetTransition(newState); } } public void FixedUpdate() { _state.FixedUpdate(); } public void SetTransition(IState state) { // 다음음 상태로 전환 _state = state; _state.Enter(); } } public interface IState { void Enter(); void Update(); void FixedUpdate(); // FixedUpdate 추가 void Exit(); // 트리거 조건일 경우 다음 상태로 전환 IState CheckTransition(); } public class IdleState : IState { private PlayerMove _player; // PlayerMove 객체에 대한 참조 private MoveState _moveState; private JumpState _jumpState; public IdleState(PlayerMove player) { _player = player; } public void Enter() { _player.Animator.SetBool(PlayerMove.IsMoving, false); } public void Update() { // 상태별 로직은 여기서는 필요 없음 } public void FixedUpdate() { // 물리적인 로직이 없으므로 비워둠 } public void Exit() { // Idle 상태에서 벗어날 때의 로직 } public IState CheckTransition() { if (Input.GetButtonDown("Jump")) { return new JumpState(_player); // Create new JumpState object } if (Mathf.Abs(Input.GetAxisRaw("Horizontal")) > 0) { return new MoveState(_player); // Create new MoveState object } return this; } } public class MoveState : IState { private PlayerMove _player; private IdleState _idleState; private JumpState _jumpState; public MoveState(PlayerMove player) { _player = player; } public void Enter() { _player.Animator.SetBool(PlayerMove.IsMoving, true); } public void Update() { // 상태별 로직 _player.SpriteRenderer.flipX = Input.GetAxisRaw("Horizontal") > 0; } public void FixedUpdate() { float h = Input.GetAxisRaw("Horizontal"); _player.RigidBody.AddForce(Vector2.right * h, ForceMode2D.Impulse); if (_player.RigidBody.linearVelocity.x > _player.maxSpeed) { _player.RigidBody.linearVelocity = new Vector2(_player.maxSpeed, _player.RigidBody.linearVelocity.y); } else if (_player.RigidBody.linearVelocity.x < -_player.maxSpeed) { _player.RigidBody.linearVelocity = new Vector2(-_player.maxSpeed, _player.RigidBody.linearVelocity.y); } } public void Exit() { // 이동 상태에서 벗어날 때 필요한 로직 _player.Animator.SetBool(PlayerMove.IsMoving, false); } public IState CheckTransition() { if (Input.GetButtonDown("Jump")) { return new JumpState(_player); // Create new JumpState object } if (Mathf.Abs(Input.GetAxisRaw("Horizontal")) < 0.1f) { return new IdleState(_player); // Create new IdleState object } return this; } } public class JumpState : IState { private PlayerMove _player; private IdleState _idleState; public JumpState(PlayerMove player) { _player = player; } public void Enter() { _player.RigidBody.AddForce(Vector2.up * _player.jumpPower, ForceMode2D.Impulse); _player.Animator.SetBool(PlayerMove.IsJumping, true); } public void Update() { // 점프 중 스프라이트 방향 변경 if (Input.GetButton("Horizontal")) { _player.SpriteRenderer.flipX = Input.GetAxisRaw("Horizontal") > 0; } } public void FixedUpdate() { // FixedUpdate에 물리 로직이 없으므로 비워둠 } public void Exit() { _player.Animator.SetBool(PlayerMove.IsJumping, false); } public IState CheckTransition() { if (_player.RigidBody.linearVelocity.y < 0) { RaycastHit2D rayHit = Physics2D.Raycast(_player.RigidBody.position, Vector3.down, 1, LayerMask.GetMask("Platform")); if (rayHit.collider != null && rayHit.distance < 0.7f) { return new IdleState(_player); // Create new IdleState object } } return this; } } public class AttackState : IState { private PlayerMove _player; private IdleState _idleState; public AttackState(PlayerMove player) { _player = player; } public void Enter() { } public void Update() { } public void FixedUpdate() { } public void Exit() { // _player.Animator.SetBool(PlayerMove.IsAttacking, false); } public IState CheckTransition() { // 공격이 종료됐을 때 // idle return this; } }