From 21a20038303ece2f98eb5684a03ae82725601dea Mon Sep 17 00:00:00 2001 From: Mingu Kim Date: Sun, 17 Aug 2025 23:25:41 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B0=81=20=EC=83=81=ED=83=9C=EB=A5=BC=20?= =?UTF-8?q?=EB=8B=B4=EC=9D=84=20=EC=88=98=20=EC=9E=88=EB=8A=94=20=EB=94=95?= =?UTF-8?q?=EC=85=94=EB=84=88=EB=A6=AC=EC=97=90=20=EC=83=81=ED=83=9C=20?= =?UTF-8?q?=EC=A0=80=EC=9E=A5=ED=95=98=EB=8F=84=EB=A1=9D=20=EA=B5=AC?= =?UTF-8?q?=EC=A1=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/Scripts/Player/PlayerMove.cs | 25 +++--- Assets/Scripts/Player/StateMachine.cs | 112 +++++++++++--------------- 2 files changed, 60 insertions(+), 77 deletions(-) diff --git a/Assets/Scripts/Player/PlayerMove.cs b/Assets/Scripts/Player/PlayerMove.cs index d6682791..f8547252 100644 --- a/Assets/Scripts/Player/PlayerMove.cs +++ b/Assets/Scripts/Player/PlayerMove.cs @@ -8,13 +8,6 @@ public class PlayerMove : MonoBehaviour public SpriteRenderer SpriteRenderer { get; private set; } public Animator Animator { get; private set; } - // 다른 클래스에서 접근할 수 있도록 private static 변수와 public 프로퍼티를 분리 - private static int _isJumping; - private static int _isMoving; - - public static int IsJumping => _isJumping; - public static int IsMoving => _isMoving; - public float maxSpeed; public float jumpPower; @@ -41,11 +34,7 @@ public class PlayerMove : MonoBehaviour return; } - // 2. Animator가 초기화된 후에 해시 값 할당 - _isJumping = Animator.StringToHash("isJumping"); - _isMoving = Animator.StringToHash("isMoving"); - - _stateMachine = new StateMachine(new IdleState(this)); + _stateMachine = new StateMachine(State.IDLE, this); } private void Update() @@ -55,7 +44,17 @@ public class PlayerMove : MonoBehaviour void FixedUpdate() { - _stateMachine.FixedUpdate(); + float h = Input.GetAxisRaw("Horizontal"); + RigidBody.AddForce(Vector2.right * h, ForceMode2D.Impulse); + + if (RigidBody.linearVelocity.x > maxSpeed) + { + RigidBody.linearVelocity = new Vector2(maxSpeed, RigidBody.linearVelocity.y); + } + else if (RigidBody.linearVelocity.x < -maxSpeed) + { + RigidBody.linearVelocity = new Vector2(-maxSpeed, RigidBody.linearVelocity.y); + } } void OnCollisionEnter2D(Collision2D collision) diff --git a/Assets/Scripts/Player/StateMachine.cs b/Assets/Scripts/Player/StateMachine.cs index 48d627d2..c71f1fa5 100644 --- a/Assets/Scripts/Player/StateMachine.cs +++ b/Assets/Scripts/Player/StateMachine.cs @@ -1,12 +1,28 @@ +using System.Collections.Generic; using UnityEngine; +public enum State +{ + IDLE, MOVE, JUMP +} + public class StateMachine { - private IState _state; - - public StateMachine(IState state) + private IState _state; + private State _currentState; + + //장점 : key 값을 바로 불러와서 value를 리턴할 수 있게 된다. (자료구조가 많은 데이터를 담았을 때 리턴하는 경우 속도의 효율) + //단점 : 자료구조의 데이터가 적을 때, 100개 혹은 10 이하의 데이터에서 Dictionary를 사용할 경우 속도가 오히려 느릴 수 있다. + private Dictionary _states = new Dictionary(); + + public StateMachine(State state, PlayerMove player) { - _state = state; + _states.Add(State.IDLE, new IdleState(player)); + _states.Add(State.MOVE, new MoveState(player)); + _states.Add(State.JUMP, new JumpState(player)); + + _currentState = state; + _state = _states[state]; _state.Enter(); } @@ -16,22 +32,18 @@ public class StateMachine var newState = _state.CheckTransition(); // 상태가 변경되었는지 확인 (참조가 다르면) - if (_state != newState) + if (_currentState != newState) { _state.Exit(); SetTransition(newState); } } - public void FixedUpdate() - { - _state.FixedUpdate(); - } - - public void SetTransition(IState state) + public void SetTransition(State state) { // 다음음 상태로 전환 - _state = state; + _currentState = state; + _state = _states[state]; _state.Enter(); } } @@ -42,19 +54,15 @@ public interface IState void Update(); - void FixedUpdate(); // FixedUpdate 추가 - void Exit(); // 트리거 조건일 경우 다음 상태로 전환 - IState CheckTransition(); + State CheckTransition(); } public class IdleState : IState { private PlayerMove _player; // PlayerMove 객체에 대한 참조 - private MoveState _moveState; - private JumpState _jumpState; public IdleState(PlayerMove player) { @@ -63,7 +71,7 @@ public class IdleState : IState public void Enter() { - _player.Animator.SetBool(PlayerMove.IsMoving, false); + // _player.Animator.SetBool(PlayerMove.IsMoving, false); } public void Update() @@ -71,35 +79,30 @@ public class IdleState : IState // 상태별 로직은 여기서는 필요 없음 } - public void FixedUpdate() - { - // 물리적인 로직이 없으므로 비워둠 - } - public void Exit() { // Idle 상태에서 벗어날 때의 로직 } - public IState CheckTransition() + public State CheckTransition() { if (Input.GetButtonDown("Jump")) { - return new JumpState(_player); // Create new JumpState object + return State.JUMP; } if (Mathf.Abs(Input.GetAxisRaw("Horizontal")) > 0) { - return new MoveState(_player); // Create new MoveState object + return State.MOVE; } - return this; + return State.IDLE; } } public class MoveState : IState { + private static int _isMoving = Animator.StringToHash("isMoving"); + private PlayerMove _player; - private IdleState _idleState; - private JumpState _jumpState; public MoveState(PlayerMove player) { @@ -108,7 +111,7 @@ public class MoveState : IState public void Enter() { - _player.Animator.SetBool(PlayerMove.IsMoving, true); + _player.Animator.SetBool(_isMoving, true); } public void Update() @@ -116,46 +119,32 @@ public class MoveState : IState // 상태별 로직 _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); + _player.Animator.SetBool(_isMoving, false); } - public IState CheckTransition() + public State CheckTransition() { if (Input.GetButtonDown("Jump")) { - return new JumpState(_player); // Create new JumpState object + return State.JUMP; } if (Mathf.Abs(Input.GetAxisRaw("Horizontal")) < 0.1f) { - return new IdleState(_player); // Create new IdleState object + return State.IDLE; // Create new IdleState object } - return this; + return State.MOVE; } } public class JumpState : IState { + private static int _isJumping = Animator.StringToHash("isJumping"); + private PlayerMove _player; - private IdleState _idleState; public JumpState(PlayerMove player) { @@ -165,7 +154,7 @@ public class JumpState : IState public void Enter() { _player.RigidBody.AddForce(Vector2.up * _player.jumpPower, ForceMode2D.Impulse); - _player.Animator.SetBool(PlayerMove.IsJumping, true); + _player.Animator.SetBool(_isJumping, true); } public void Update() @@ -177,17 +166,12 @@ public class JumpState : IState } } - public void FixedUpdate() - { - // FixedUpdate에 물리 로직이 없으므로 비워둠 - } - public void Exit() { - _player.Animator.SetBool(PlayerMove.IsJumping, false); + _player.Animator.SetBool(_isJumping, false); } - public IState CheckTransition() + public State CheckTransition() { if (_player.RigidBody.linearVelocity.y < 0) { @@ -195,10 +179,10 @@ public class JumpState : IState if (rayHit.collider != null && rayHit.distance < 0.7f) { - return new IdleState(_player); // Create new IdleState object + return State.IDLE; } } - return this; + return State.JUMP; } } @@ -232,10 +216,10 @@ public class AttackState : IState // _player.Animator.SetBool(PlayerMove.IsAttacking, false); } - public IState CheckTransition() + public State CheckTransition() { // 공격이 종료됐을 때 // idle - return this; + return State.IDLE; } } \ No newline at end of file