Menu
CoddyTech

상태 전환하기

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

게임의 각 상태는 매 프레임마다 서로 다른 작업을 수행합니다. 상태 필드에 대한 switch문을 사용하면 상태별로 하나의 케이스에 해당 작업을 넣을 수 있고, 매 프레임 정확히 하나의 케이스가 실행됩니다. 상태 변경은 하나의 메서드를 거치므로 화면은 항상 상태와 일치합니다. 이 보스전에는 인트로, 전투, 승리 화면이 있습니다.

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);
    }
}

C#에서는 하나의 케이스가 다음 케이스까지 이어서 실행되는 경우 컴파일을 허용하지 않으므로 각 케이스는 break로 끝납니다. 인트로의 타이머가 끝나면 Enter(Phase.Fight)가 페이즈를 변경하지만, 이 프레임은 이미 실행할 케이스를 선택했으므로 Fight 케이스는 다음 프레임에 처음 실행됩니다. if 블록을 여러 개 이어서 사용하면 한 프레임 안에서 전투를 시작하고 전투 코드까지 실행할 수 있습니다.

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

challenge icon

챌린지

쉬움

5초 탭 경주를 만드세요.

  1. SetState에서 새 상태의 패널만 표시하세요. Playing 상태에 들어가면 taps = 0, timeLeft = roundTime 및 Taps: 0을 설정하고, GameOver 상태에 들어가면 resultText에 Taps: 3을 표시하세요.
  2. Update()에서 switch (state)를 사용하세요. Space를 누르면 Ready에서 Playing으로, GameOver에서 Ready로 이동합니다. Playing 상태에서는 시간이 다 될 때까지 Space를 누를 때마다 taps와 tapsText의 횟수를 늘리세요.

‘플레이’를 누르고 두 번 경주하세요. 그런 다음 ‘확인’을 누르세요.

직접 해보기

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;
        // 새 상태의 패널만 표시한다
        // 새 라운드는 탭 0회와 roundTime초로 시작하며, 종료 시 resultText에 탭 횟수를 표시한다
    }
}

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

직접 연습해 보세요: Unity 플레이그라운드