집씬으로 넘기기

This commit is contained in:
2026-07-14 16:34:20 +09:00
parent b87651b186
commit e0be196bbb
15 changed files with 213 additions and 20 deletions

View File

@@ -1,6 +1,7 @@
using System;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.Serialization;
using UnityEngine.XR.Interaction.Toolkit.Locomotion;
public class SceneLoadManager : MonoBehaviour
@@ -11,8 +12,10 @@ public class SceneLoadManager : MonoBehaviour
[SerializeField] private Camera _loadingCam;
[SerializeField] private Transform _loadingCamTargetTransform;
[SerializeField] private LoadingScreen _loadingScreen;
[SerializeField] private Material _sceneSkybox;
// 씬(LocalManager)이 전용 스카이박스를 지정하지 않았을 때 쓰는 기본 스카이박스
// (FormerlySerializedAs: 프리팹에 _sceneSkybox로 저장돼 있던 연결을 유지)
[FormerlySerializedAs("_sceneSkybox")]
[SerializeField] private Material _defaultSceneSkybox;
[SerializeField] private Material _loadingSkybox;
[SerializeField, Min(0f)] private float _skyboxFadeTime = 1f;
@@ -25,6 +28,9 @@ public class SceneLoadManager : MonoBehaviour
private Material _runtimeSceneSkybox;
private Material _runtimeLoadingSkybox;
// 씬 전환 시퀀스 진행 중 여부 — 이때 적용되는 새 스카이박스는 검은 상태로 시작해야 한다
private bool _isChangingScene;
private void Awake()
{
if (Instance == null)
@@ -36,16 +42,11 @@ private void Awake()
Destroy(gameObject); // 이미 인스턴스가 있으면 자신을 파괴
}
if (_sceneSkybox != null)
_runtimeSceneSkybox = new Material(_sceneSkybox);
if (_loadingSkybox != null)
_runtimeLoadingSkybox = new Material(_loadingSkybox);
if (_runtimeSceneSkybox != null)
{
RenderSettings.skybox = _runtimeSceneSkybox;
DynamicGI.UpdateEnvironment();
}
// 씬용 스카이박스는 OnSceneLoaded → SetSceneSkybox에서 적용된다
// (기본 스카이박스를 깔고, 씬에 LocalManager가 있으면 씬 전용으로 덮어씀)
}
private void Start()
@@ -75,6 +76,10 @@ private void Update()
// 씬이 로드되었을때 호출
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
// 우선 기본 스카이박스를 적용 — 씬 전용 스카이박스가 있으면
// 아래 루프에서 그 씬의 LocalManager가 SetSceneSkybox로 덮어쓴다
SetSceneSkybox(null);
MonoBehaviour[] allObjs = FindObjectsByType<MonoBehaviour>();
foreach (var obj in allObjs)
@@ -87,6 +92,24 @@ private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
}
}
// 현재 씬에서 쓸 스카이박스를 지정한다 (null이면 기본 스카이박스로).
// 페이드가 머티리얼 에셋 원본의 _Exposure를 오염시키지 않도록 항상 복사본을 만들어 쓴다.
public void SetSceneSkybox(Material skybox)
{
var source = skybox != null ? skybox : _defaultSceneSkybox;
if (source == null) return;
if (_runtimeSceneSkybox != null) Destroy(_runtimeSceneSkybox);
_runtimeSceneSkybox = new Material(source);
// 씬 전환 중이면 아직 어두워야 한다 — 마지막 페이드 인(0 → 기본 노출)이 밝혀준다
if (_isChangingScene && _runtimeSceneSkybox.HasFloat("_Exposure"))
_runtimeSceneSkybox.SetFloat("_Exposure", 0f);
RenderSettings.skybox = _runtimeSceneSkybox;
DynamicGI.UpdateEnvironment();
}
public async Awaitable FadeLoadingCanvas(bool isOut,float fadeTime)
{
float startAlpha = isOut ? 1f : 0f;
@@ -190,6 +213,8 @@ private async Awaitable SceneChange(string sceneName)
{
try
{
_isChangingScene = true;
//로딩바 수치 0으로 설정
SetSceneLoadingProgressValue(0f);
@@ -276,5 +301,9 @@ private async Awaitable SceneChange(string sceneName)
{
Debug.Log("씬 전환 작업이 취소됨");
}
finally
{
_isChangingScene = false;
}
}
}