Menu
CoddyTech

상태 전환하기

Coddy Unity 여정의 실제 게임 만들기 섹션에 포함된 레슨. 56개 중 15번째.

게임의 각 상태는 매 프레임마다 서로 다른 작업을 수행합니다. 상태 필드에 대한 switch를 사용하면 각 상태마다 하나의 case에 해당 작업을 배치할 수 있으며, 매 프레임 정확히 하나의 case가 실행됩니다. 상태 변경은 하나의 메서드를 통해 이루어지므로 화면은 항상 상태와 일치합니다. 이 보스전에는 도입부, 전투, 승리 화면이 있습니다:

public enum Phase { Intro, Fight, Won }

public class BossFight : MonoBehaviour
{
    public GameObject introPanel;
    public GameObject fightPanel;
    public GameObject winPanel;
    public int bossHp = 10;
    private Phase phase;
    private float timer = 3f;

    void Start()
    {
        Enter(Phase.Intro);
    }

    void Update()
    {
        switch (phase)
        {
            case Phase.Intro:
                timer -= Time.deltaTime;
                if (timer <= 0f) Enter(Phase.Fight);
                break;
            case Phase.Fight:
                if (bossHp <= 0) Enter(Phase.Won);
                break;
            case Phase.Won:
                break;
        }
    }

    void Enter(Phase next)
    {
        phase = next;
        introPanel.SetActive(next == Phase.Intro);
        fightPanel.SetActive(next == Phase.Fight);
        winPanel.SetActive(next == Phase.Won);
    }
}

각 case는 break로 끝납니다. C#에서는 다음 case로 이어서 실행되는 case를 컴파일할 수 없기 때문입니다. 도입부의 타이머가 끝나면 Enter(Phase.Fight)가 페이즈를 변경하지만, 이 프레임에 실행할 case는 이미 선택되었으므로 Fight case는 다음 프레임에 처음 실행됩니다. if 블록을 따로 연이어 사용하면, 한 프레임에 전투를 시작하고 같은 프레임에 전투 코드를 실행할 수도 있습니다.

Enter만이 phase를 변경하는 곳입니다. next == Phase.Fight는 전투 패널에 대해서만 true이므로, 한 번 호출하면 해당 패널이 표시되고 나머지 두 패널은 숨겨집니다. 타이머 초기화처럼 상태 진입에 필요한 작업도 Enter에 넣으면 매 프레임이 아니라 한 번만 실행됩니다.

challenge icon

챌린지

쉬움

탭 경주: 5초 동안 스페이스바를 몇 번 누를 수 있나요? GameManager에는 GameState 열거형(Ready, Playing, GameOver), 각 상태에 해당하는 패널이 있으며, Start는 SetState(GameState.Ready)를 호출합니다. Update와 SetState를 작성하세요.

Update에서 state를 기준으로 switch 문을 사용하세요.

  • Ready: 스페이스바를 누르면 라운드가 시작됩니다. 이때 누른 것은 탭으로 세지 않습니다.
  • Playing: 스페이스바를 누를 때마다 taps에 1을 더하고, Taps: 3처럼 tapsText에 표시합니다. roundTime초(5초)가 지나면 게임이 끝납니다.
  • GameOver: 스페이스바를 누르면 Ready로 돌아갑니다.

SetState(GameState next)는 state를 설정하고 새 상태의 패널만 표시합니다. Playing 상태로 들어가면 탭 수를 0으로 하여 라운드를 시작하고, 화면에 Taps: 0을 표시하며 남은 시간은 roundTime초로 설정합니다. GameOver 상태로 들어가면 Taps: 3처럼 결과를 resultText에 표시합니다.

Play를 누르고, 두 번 경주한 다음 Check를 누르세요.

직접 해보기

using UnityEngine;
using TMPro;

public enum GameState { Ready, Playing, GameOver }

public class GameManager : MonoBehaviour
{
    public GameObject readyPanel;
    public GameObject playPanel;
    public GameObject gameOverPanel;
    public TMP_Text tapsText;
    public TMP_Text resultText;
    public float roundTime = 5f;
    public GameState state;
    private int taps;
    private float timeLeft;

    void Start()
    {
        SetState(GameState.Ready);
    }

    void Update()
    {
        // state에 따라 분기:
        // Ready: Space를 누르면 라운드 시작
        // Playing: Space를 누를 때마다 탭 횟수를 세고, 시간이 다 되면 게임 종료
        // GameOver: Space를 누르면 Ready로 돌아감
    }

    void SetState(GameState next)
    {
        state = next;
        // 새 state의 패널만 표시
        // 새 라운드는 탭 횟수 0과 roundTime초로 시작하며, 종료 시 resultText에 탭 횟수가 표시됨
    }
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

실제 게임 만들기의 모든 레슨