티스토리 뷰

드디어 StateMachine을 제대로 적용해봤다. 이해하고 적용하는데 시간이 좀 걸렸지만 코드가 훨씬 깔끔해졌고 확실히 유지보수에 용이할 것 같다!


💻 Unity

Velocity

  • Rigidbody.velocity는 물체의 현재 속도를 나타내는 벡터
  • 이 벡터는 방향 + 속도의 크기를 함께 가지고 있다
    • 예: (1, 0, 0)이면 x축 방향으로 1 단위 속도로 움직이는 중
  • 단위는 미터/초(m/s)
Rigidbody rb = GetComponent<Rigidbody>();

void Update()
{
    float move = Input.GetAxis("Horizontal");
    rb.velocity = new Vector3(move * 5f, rb.velocity.y, 0f);
}

주의사항

Rigidbody 필수 velocity는 Rigidbody가 있어야 작동 (2D면 Rigidbody2D.velocity)
직접 제어 velocity를 직접 설정하면, 힘이나 중력의 영향보다 우선. 즉, 순간 이동처럼 작동할 수 있다
이동 제어 Translate()와 달리, velocity는 물리 연산과 충돌 감지를 포함하므로 자연스럽게 움직인

🕹️ 실습 (2D 횡스크롤 2)

StateMachine으로 Player 애니메이션 구현

현재 상태 조건  전환 상태
PlayerIdleState 이동 입력이 있을 때 PlayerMoveState
  점프 입력이 있을 때 PlayerJumpState
  대시 입력이 있을 때 PlayerDashState
PlayerMoveState 이동 입력이 없을 때 PlayerIdleState
  점프 입력이 있을 때 PlayerJumpState
  대시 입력이 있을 때 PlayerDashState
PlayerJumpState 공중에 있을 때 PlayerAirState
  착지했을 때 PlayerIdleState 또는 PlayerMoveState
PlayerAirState 착지했을 때 PlayerIdleState 또는 PlayerMoveState
PlayerDashState 대시가 끝났을 때 PlayerIdleState 또는 PlayerMoveState

📝 과제

벽타기 구현

// Player.cs

public bool IsWallDetected() // 추가
{
    return Physics2D.Raycast(wallCheck.position, Vector2.right, wallCheckDistance * facingDir, whatIsGround);
}

private void OnDrawGizmos()
{
    Gizmos.DrawLine(groundCheck.position, new Vector3(groundCheck.position.x, groundCheck.position.y - groundCheckDistance));
    Gizmos.DrawLine(wallCheck.position, new Vector3(wallCheck.position.x + wallCheckDistance * facingDir, wallCheck.position.y)); // 수정
}

public void Flip()
{
    facingDir = facingDir * -1;
    isFacingRight = !isFacingRight;
    transform.Rotate(0, 180, 0);
}
public class PlayerAirState : PlayerState
{
    public PlayerAirState(Player _player, PlayerStateMachine _stateMachine, string _animBoolName) 
        : base(_player, _stateMachine, _animBoolName)
    {

    }

    public override void Enter()
    {
        base.Enter();
    }

    public override void Update()
    {
        base.Update();

        if (player.IsGroundDetected())
        {
            stateMachine.ChangeState(player.idleState);
        }

        if (player.IsWallDetected()) // 추가
        {
            stateMachine.ChangeState(player.hangingState);
        }
    }

    public override void Exit()
    {
        base.Exit();
    }
}

public class PlayerHangingState : PlayerState
{
    public PlayerHangingState(Player _player, PlayerStateMachine _stateMachine, string _animBoolName) 
        : base(_player, _stateMachine, _animBoolName)
    {

    }

    public override void Enter()
    {
        base.Enter();
    }

    public override void Update()
    {
        base.Update();
				
        player.SetVelocity(rb.linearVelocityX, Mathf.Max(rb.linearVelocityY, -player.slideSpeed));

        if (Input.GetKeyDown(KeyCode.Space))
        {
            float jumpDirection = player.facingDir * -1;
            rb.linearVelocity = new Vector2(jumpDirection * player.moveSpeed, player.jumpForce);
            player.Flip();
            stateMachine.ChangeState(player.jumpState);
        }

        if (!player.IsWallDetected() && !player.IsGroundDetected())
        {
            stateMachine.ChangeState(player.airState);
        }

        if (player.IsGroundDetected())
        {
            stateMachine.ChangeState(player.idleState);
        }
    }

    public override void Exit()
    {
        base.Exit();
    }
}

 

느리게 슬라이딩

player.SetVelocity(rb.linearVelocityX, Mathf.Max(rb.linearVelocityY, -player.slideSpee

플레이어가 벽에 매달려 있을 때, 중력에 의해 rb.linearVelocityY는 점점 음수로 커진다 (예: -1, -2, -3, ...)

하지만 Mathf.Max(rb.linearVelocityY, -player.slideSpeed) y축 속도가 -player.slideSpeed보다 더 음수(더 빠르게 떨어지는 값)가 되지 않도록 제한한다

 

반대 방향으로 점프

if (Input.GetKeyDown(KeyCode.Space))
{
    float jumpDirection = player.facingDir * -1;
    rb.linearVelocity = new Vector2(jumpDirection * player.moveSpeed, player.jumpForce);
    player.Flip();
    stateMachine.ChangeState(player.jumpState);
}

현재 벽을 바라보는 방향에서 반대 방향으로 가속을 준 후 Flip한 후 점프 동작으로 전환한다

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
글 보관함