[Unity] Rigidbody 초기화부터 enum 리팩토링까지

shin0112·2025년 10월 28일

Unity

목록 보기
5/13

✨ 들어가며

오늘은 GetFruit 미니게임에서 드론이 혼자 움직이는 버그를 해결했다.
처음엔 isFlap 값이 잘못 들어간 줄 알았는데, 결국 원인은 중력과 상태 관리 구조였다.

1️⃣ 중력이 적용되지 않은 채 남아있던 힘

포탈을 통해 미니게임으로 들어갈 때 드론이 대각선 방향으로 계속 떠오르는 현상이 있었다.

처음엔 “플랩이 자동으로 눌리는 건가?” 싶었는데 로그를 찍어보니 isFlap은 한 번도 호출되지 않았다.

원인은 단순했다.

중력이 꺼져 있어서 기존 이동 힘이 그대로 남아있던 것.

velocity가 유지된 채로 씬만 전환되니까 중력 없이 그 방향으로 계속 밀려가고 있었던 것이다.
그래서 미니게임 진입 시 Rigidbody2D 값을 전부 리셋하도록 수정했다.

var playerRb = _player.GetComponent<Rigidbody2D>();
playerRb.gravityScale = 1f;          // 중력 다시 켜기
playerRb.velocity = Vector2.zero;    // 남은 힘 제거
playerRb.angularVelocity = 0f;       // 회전값 초기화

변경 후에는 어떤 상태로 들어가도 항상 같은 조건에서 시작된다.

  • 이동 중 진입해도 정상 낙하
  • 드론이 혼자 하늘로 뜨는 현상 사라짐

2️⃣ bool로 상태 관리하던 구조

처음엔 아래처럼 여러 bool로 상태를 나누었다.

bool _isPrepare;
bool _isReady;
bool _isStart;
bool _isDead;
int  _deadCount;

이렇게 여러 bool 값으로 관리를 하게 되니,
어떤 타이밍에 true로 바꿔야 하는지 계속 헷갈리고,
한쪽이 켜진 채로 다른 쪽이 안 꺼져 있어서 혼자 알아서 시작하는 버그도 발생했다.

OnReady()랑 StartGame()이 같은 프레임에 호출되면서 Ready → Start가 한 번에 넘어가는 일도 있었다.

3️⃣ enum으로 상태 통합

결국 bool을 전부 없애고 enum으로 바꿨다.

public enum MiniGameState
{
    Stop,   // 초기 상태
    Ready,  // 준비 완료
    Start,  // 실제 시작
    Dead,   // 사망
    End     // 종료
}

이제 CurrentState 하나로 전부 관리한다.

protected virtual void Update()
{
    if (_controller == null) return;

    if (CurrentState is MiniGameState.Stop && CheckStartInput())
    {
        OnReady();
    }
    else if (CurrentState is MiniGameState.Ready && CheckStartInput())
    {
        StartGame();
    }
    else if (CurrentState is MiniGameState.Start)
    {
        OnPlaying();
    }
}

if 대신 else if로 바꿔서
Ready → Start로 바로 넘어가는 문제도 같이 해결됐다.

4️⃣ 결과

구분변경 전변경 후
상태 관리여러 bool 조합enum 단일 상태
흐름 제어꼬이기 쉬운 분기명확한 상태 전이
버그 발생Ready→Start 동시 실행단계별 실행
가독성낮음높음

✍️ 마치며

이번 문제는 단순한 버그가 아니라 구조 문제였다.
씬이 바뀌더라도 물리 상태(velocity, gravityScale)는 남아있고,
bool로 나눈 상태는 언제든 꼬일 수 있다.

해결책은 아래와 같다.

  • 진입할 때 물리값은 전부 리셋
  • 상태는 enum 하나로 관리

이제는 흐름이 한눈에 보이고,
Ready → Start → Dead → End까지 전이 구조도 명확해졌다.

0개의 댓글