씬 간에 유지하기
Coddy Unity 여정의 실제 게임 만들기 섹션에 포함된 레슨. 60개 중 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가 프레임 끝까지 기다리기 때문입니다. return이 없으면 새 오브젝트에서 Awake의 나머지 부분이 계속 실행됩니다. 그러면 Instance = this;가 모든 스크립트가 곧 파괴될 오브젝트를 가리키게 만듭니다.
챌린지
쉬움모든 장면이 로드되는 동안 하나의 실행 시계를 계속 유지하세요.
Awake()에서Instance != null이면Destroy(gameObject);를 호출하고return;을 실행하세요. 그렇지 않으면Instance를 설정하고DontDestroyOnLoad(gameObject);를 호출하세요.- 장면을 로드하면 이전 레벨의 텍스트가 삭제되므로,
Update()에서 텍스트 줄 앞에clockText == null일 때clockText = GameObject.Find("ClockText").GetComponent<TMP_Text>();를 설정하세요.
‘플레이’를 누르고 Level2로 갔다가 돌아오세요. 시계 하나가 계속 시간을 셉니다. 그런 다음 ‘확인’을 누르세요.
직접 해보기
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"));
}
}
실제 게임 만들기의 모든 레슨
직접 연습해 보세요: Unity 플레이그라운드