Menu
CoddyTech

씬 간에 유지하기

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

씬을 로드하면 이전 씬의 모든 오브젝트가 파괴되지만, 플레이어가 레벨마다 가지고 다니는 코인처럼 게임 전체에서 유지되어야 하는 것도 있습니다. DontDestroyOnLoad(gameObject)는 오브젝트를 현재 씬에서 꺼내 자체 씬으로 옮깁니다. 이 씬은 플레이 중 Hierarchy에서 DontDestroyOnLoad라고 표시되며, 씬 로드의 영향을 받지 않습니다. 이 기능은 루트 오브젝트에만 적용됩니다. 자식 오브젝트에 적용하면 Unity는 경고를 기록하고 아무것도 유지하지 않습니다. 유지되는 오브젝트의 자식은 함께 따라오지만, 단지 참조만 하는 오브젝트는 따라오지 않습니다. 로드가 끝나면 이전 씬의 오브젝트를 가리키던 필드는 파괴된 오브젝트를 가지며, 이 오브젝트는 null과 같다고 판단됩니다.

public class GameSession : MonoBehaviour
{
    public static GameSession Instance;
    public int coins;

    void Awake()
    {
        if (Instance != null)
        {
            Destroy(gameObject);
            return;
        }
        Instance = this;
        DontDestroyOnLoad(gameObject);
    }
}

이 GameSession은 Menu 씬에 있습니다. 플레이하면 Menu에서 Level1로 이동한 다음 다시 Menu로 돌아오는데, 이때 Menu는 유지된 GameSession을 포함해 모든 오브젝트를 새로 생성합니다. 기존 GameSession은 여전히 남아 있습니다. Awake에서 확인하지 않으면 두 개가 생기고, 새로 생성된 GameSession이 0개의 코인을 가진 채 Instance를 차지하게 됩니다. 확인 코드가 있으면 새 GameSession은 Instance가 이미 설정된 것을 확인하고, 자신을 파괴한 뒤 실행을 멈춥니다. 레벨을 거쳐 온 세션은 그대로 유지됩니다.

return이 중요한 이유는 Destroy가 프레임 끝까지 실행을 기다리기 때문입니다. 이 코드가 없으면 새 오브젝트에 대해 Awake의 나머지 부분도 계속 실행됩니다. 그러면 Instance = this;가 모든 스크립트에서 곧 파괴될 오브젝트를 가리키게 됩니다.

challenge icon

챌린지

쉬움

스피드런 시계입니다. Level1의 RunClock 객체는 전체 달리기 시간을 초 단위로 세고 레벨을 완료할 때마다 스플릿 시간을 기록합니다. Level1의 금색 Goal은 Level2를 불러오고, Level2의 Goal은 다시 Level1을 불러오며, 각 Goal은 먼저 RunClock.Instance.Split()을 호출합니다. 각 레벨에는 ClockText가 있는 자체 HUD가 있으며, Inspector에서는 RunClock에 Level1의 ClockText를 지정합니다. 화살표 키로 Player를 이동합니다. 다음과 같이 RunClock.cs를 변경하세요.

  • 시계가 처음부터 다시 시작되지 않고 모든 씬 로드 중에도 계속 작동해야 합니다.
  • 시간은 열린 레벨의 ClockText에 항상 Time: 12.3 형식으로 표시되어야 합니다.
  • 자체 RunClock이 있는 Level1로 돌아와도 계속 실행 중이던 시계 하나만 남아야 하며, RunClock.Instance는 그 시계여야 합니다.

Play를 누르고 Level2로 갔다가 돌아온 다음 Level1을 다시 완료하고 Check를 누르세요.

직접 해보기

using UnityEngine;
using TMPro;

public class RunClock : MonoBehaviour
{
    public static RunClock Instance;
    public TMP_Text clockText;
    private float seconds;

    void Awake()
    {
        Instance = this;
    }

    void Update()
    {
        seconds += Time.deltaTime;
        clockText.text = "Time: " + seconds.ToString("0.0");
    }

    public void Split()
    {
        Debug.Log("Split: " + seconds.ToString("0.0"));
    }
}
quiz icon실력 점검

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

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