유니티 씬 삭제 - yuniti ssin sagje

pais

유니티 씬 삭제 - yuniti ssin sagje
SKIAP


«   2022/12   »

1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

관리 메뉴

  • 글쓰기
  • 방명록
  • RSS
  • 관리

pais

카테고리 없음

[unity] 오브젝트 씬이동 시 삭제 안되도록 인스턴스

SKIAP 2020. 10. 9. 07:25

[unity] 오브젝트 씬이동 시 삭제 안되도록

1. DontDestroyOnLoad

2. 씬 이동 시재생성 안되도록 인스턴스화

public class TestManager : MonoBehaviour
{
	public static TestManager instance = null;
	void Awake()
	{
		if (instance == null)
			instance = this;
 
		else if (instance != this)
			Destroy(gameObject);    
 
		DontDestroyOnLoad(gameObject);
 
	}
}


도메인 및 씬 재로드 비활성화에 대한 세부 정보

씬 재로드

기본적으로 씬 재로드는 활성화됩니다. 즉 플레이 모드를 시작하면 Unity는 모든 기존 씬 게임 오브젝트를 삭제하고 디스크에서 씬을 다시 로드합니다. Unity가 이 작업을 완료하는 데 걸리는 시간은 씬의 복잡도에 비례합니다. 프로젝트가 복잡해지면 플레이 버튼을 누른 후 씬에 에디터에 완전히 로드될 때까지 걸리는 시간이 길어집니다.

씬 재로드를 비활성화하면 프로세스 시간이 단축됩니다. 이렇게 하면 프로젝트 개발을 더욱 빠르게 반복할 수 있습니다. Unity는 디스크에서 씬을 다시 로드하는 대신, 씬의 수정된 콘텐츠만 초기화합니다. 따라서 씬의 언로드와 재로드가 시간과 성능에 영향을 미치지 않습니다. Unity는 새로 로드된 것처럼 여전히 동일한 초기화 함수(예: OnEnable, OnDisable, OnDestroy)를 호출합니다.

씬 재로드를 건너뛸 경우 미치는 영향

씬 재로드를 비활성화하면 에디터에서 애플리케이션을 시작하는 데 걸리는 시간이 더 이상 빌드된 버전의 시작 시간을 나타내지 않습니다. 따라서 프로젝트를 시작하는 동안 정확히 어떤 일이 발생하는지 디버깅하거나 프로파일링하려면 씬 재로드를 활성화하여 애플리케이션의 빌드된 버전에서 발생하는 실제 로드 시간과 프로세스를 더 정확하게 나타내야 합니다.

씬 재로드를 비활성화하면 프로젝트에 대한 부작용이 최소화됩니다. 하지만 씬 재로드는 도메인 재로드와 밀접한 관련이 있기 때문에 다음과 같은 몇 가지 주요 차이점이 있습니다.

  1. 빌드로 직렬화되지 않은 ScriptableObject 및 MonoBehaviour 필드([NonSerialized], 프라이빗 또는 내부)는 해당 값을 유지합니다. 이는 Unity가 기존 오브젝트를 다시 생성하지 않고 생성자를 호출하지 않기 때문입니다. 또한 Unity는 도메인 재로드 동안 배열/리스트 타입의 null 프라이빗 및 내부 필드를 빈 배열/리스트 오브젝트로 전환하고, 런타임(비 에디터) 스크립트에 대해 null이 아닌 상태를 유지합니다.

  2. ExecuteInEditMode 또는 ExecuteAlways 스크립트를 사용하는 스크립트는 OnDestroy 또는 Awake 호출을 수신합니다. Unity는 Awake를 호출하지 않으며, EditorApplication.isPlaying 프로퍼티를 확인하는 Awake/OnEnable 메서드로 플레이 모드를 변경 시 EditorApplication.isPlaying이 이미 true인 경우에만 OnEnable을 호출합니다. 런타임(비 에디터) 스크립트에 대한 직렬화되지 않은 필드는 편집 모드에서 활성화되지 않으므로 문제가 되지 않습니다. 하지만 ExecuteInEditMode 또는 ExecuteAlways로 표시된 스크립트는 자체적으로 변경되거나 다른 런타임 스크립트의 필드를 터치할 수 있습니다. 이 문제를 해결하려면 OnEnable 콜백에서 영향을 받는 모든 필드를 직접 초기화하십시오.

도메인 및 씬 재로드 비활성화에 대한 세부 정보

안녕하세요 유랑입니다.

오늘은 씬 분리와 병합에 대해서 알아보겠습니다.

씬 분리와 병합은 어떻게 해야되는 걸까요?

1. 씬 분리와 병합

다양한 사람들과 게임을 만들게 되면 씬 분리의 필요성이 확연해 집니다.

실제 게임을 구동할 때 씬을 병합하며 사용하는 것이져.

1-1) 프로젝트 생성

이름 작성과 템플릿을 선택 후 프로젝트를 생성해 주겠습니다

유니티 버전은 2019.2.1f1을 사용하겠습니다^^

1-2) 씬 분리

4개의 씬을 만들어 주겠습니다.

Main 씬을 제외한 나머지 씬들은 서브씬으로 사용될 예정입니다.

유니티 씬 삭제 - yuniti ssin sagje

1-3) 씬 병합 

Main씬을 활성화 시킨 후 Lobby 씬을 추가하면 다음과 같이

두 가지의 씬이 활성화 됩니다.

코드를 통해서 이와 같이 씬을 병합해주겠습니다.

빈 오브젝트와 스크립트를 생성 후 다음과 같이 적용해 주세요ㅎㅎ

해당 코드는 딕셔너리에 각 씬에 대한 정보 값을 저장 후

로드를 통해 씬을 병합시켜주는 코드입니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class SceneLoader : MonoBehaviour
{
    // 호출할 씬과 씬 로드 방식을 저장할 딕셔너리
    public Dictionary loadScenes = new Dictionary();

    // 호출할 씬의 정보 설정
    void InitSceneInfo()
    {
        // 호출할 씬의 정보를 딕셔너리에 추가
        loadScenes.Add("Lobby", LoadSceneMode.Additive);
        loadScenes.Add("Room", LoadSceneMode.Additive);
        loadScenes.Add("Game", LoadSceneMode.Additive);
    }

    IEnumerator Start()
    {
        InitSceneInfo();

        foreach (var _loadScene in loadScenes)
        {
            yield return StartCoroutine(LoadScene(_loadScene.Key, _loadScene.Value));
        }
    }

    IEnumerator LoadScene(string sceneName, LoadSceneMode mode)
    {
        yield return new WaitForSeconds(3.0f);

        // 기존의 씬을 언로드
        if (sceneName == "Room")
            SceneManager.UnloadSceneAsync("Lobby");
        else if (sceneName == "Game")
            SceneManager.UnloadSceneAsync("Room");

        // 씬을 로드
        SceneManager.LoadScene(sceneName, mode);
    }
}

빌드 세팅에 꼭 씬에 대한 정보를 추가해 주세요!!!

게임을 시작하면 Main씬은 계속 남아있고, 

다른 씬들이 추가 후 삭제되는 걸 확인할 수 있습니다.

1-4) FadeIn 효과

씬의 용량이 커질수록 전환시 멈춰있는 느낌을 받을 수 있습니다.

FadeIn 효과를 적용하여 자연스러운 씬 효과를 만들어 주겠습니다^^

Canvas와 Image를 각각 추가해 주세요.

이미지는 캔버스 크기에 맞게 변경 후 컬러 값은 검은색으로 바꿔 주세요.

이미지의 알파값을 이용해 페이드 효과를 주어도 되지만,

Canvas Group을 이용해 만들어 보겠습니다.

기존의 코드에 FadeIn 효과를 적용해 주겠습니다.

알파값을 변경함으로써 FadeIn 효과를 만들어 줍니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class SceneLoader : MonoBehaviour
{
    // 호출할 씬과 씬 로드 방식을 저장할 딕셔너리
    public Dictionary loadScenes = new Dictionary();

    // 호출할 씬의 정보 설정
    void InitSceneInfo()
    {
        // 호출할 씬의 정보를 딕셔너리에 추가
        loadScenes.Add("Lobby", LoadSceneMode.Additive);
        loadScenes.Add("Room", LoadSceneMode.Additive);
        loadScenes.Add("Game", LoadSceneMode.Additive);
    }

    // CanvasGroup 컴포넌트를 저장할 변수
    public CanvasGroup fadeCg;

    // Fade In 처리 시간
    [Range(0.5f, 2.0f)]
    public float fadeDuration = 1.0f;

    IEnumerator Start()
    {
        InitSceneInfo();

        foreach (var _loadScene in loadScenes)
        {
            yield return StartCoroutine(LoadScene(_loadScene.Key, _loadScene.Value));
        }
    }

    IEnumerator LoadScene(string sceneName, LoadSceneMode mode)
    {
        yield return new WaitForSeconds(fadeDuration);

        // Fade In 함수 호출
        StartCoroutine(Fade(0.0f));

        // 기존의 씬을 언로드
        if (sceneName == "Room")
            SceneManager.UnloadSceneAsync("Lobby");
        else if (sceneName == "Game")
            SceneManager.UnloadSceneAsync("Room");

        // 씬을 로드
        SceneManager.LoadScene(sceneName, mode);
    }

    // Fade In/Out 시키는 함수
    IEnumerator Fade(float finalAlpha)
    {
        // 처음 알파값을 설정(불투명)
        fadeCg.alpha = 1.0f;

        fadeCg.blocksRaycasts = true;

        // 알파값을 조정
        while (!Mathf.Approximately(fadeCg.alpha, finalAlpha))
        {
            // MoveTowoard 함수는 Lerp 함수와 동일한 함수로 알파값을 보간함
            fadeCg.alpha = Mathf.MoveTowards(fadeCg.alpha, finalAlpha, fadeDuration * Time.deltaTime);

            yield return null;
        }
        fadeCg.blocksRaycasts = false;
    }
}

코드작성이 완료되면 FadeImage를 추가하시면 완료입니다.

FadeDuration을 변경함으로써 씬과 FadeIn 시간을 변경할 수 있습니다.

2. 마무리

오늘은 씬 분리와 병합에 대해서 배워보았습니다.

씬 분리를 통해서 각각의 기능들을 나눠놓을 수 있겠네요ㅎㅎ

오늘도 고생하셨습니다.

감사합니다.

수업자료: 28.씬 분리와 병합