Add random room route system

This commit is contained in:
dldydtn9755-crypto
2026-06-11 12:59:56 +09:00
parent 43a80f2df3
commit 6a20f521ce
20 changed files with 471 additions and 23 deletions

View File

@@ -1,6 +1,7 @@
using System;
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneLoadManager : MonoBehaviour
{
public static SceneLoadManager Instance;
@@ -9,16 +10,20 @@ public class SceneLoadManager : MonoBehaviour
[SerializeField] private Camera _loadingCam;
[SerializeField] private Transform _loadingCamTargetTransform;
private bool _isChangingScene = false;
public bool IsChangingScene => _isChangingScene;
private void Awake()
{
if (Instance == null)
{
Instance = this; //만들어진 자신을 인스턴스로 설정
Instance = this; // 만들어진 자신을 인스턴스로 설정
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject); //이미 인스턴스가 있으면 자신을 파괴
Destroy(gameObject); // 이미 인스턴스가 있으면 자신을 파괴
}
}
@@ -28,15 +33,23 @@ private void Start()
OnSceneLoaded(SceneManager.GetActiveScene(), LoadSceneMode.Single);
}
private void OnDestroy()
{
if (Instance == this)
{
SceneManager.sceneLoaded -= OnSceneLoaded;
}
}
private void Update()
{
if(_loadingCamTargetTransform != null)
if (_loadingRoot != null && _loadingCamTargetTransform != null)
{
_loadingRoot.transform.position = _loadingCamTargetTransform.position;
}
}
//씬이 로드되었을때 호출
// 씬이 로드되었을때 호출
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
MonoBehaviour[] allObjs = UnityEngine.Object.FindObjectsByType<MonoBehaviour>(FindObjectsSortMode.None);
@@ -45,7 +58,7 @@ private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
if (obj is ISceneInitializable initializable)
{
//씬에서 ISceneInitializable 인터페이스를 가진 오브젝트의 초기화 로직을 실행
// 씬에서 ISceneInitializable 인터페이스를 가진 오브젝트의 초기화 로직을 실행
initializable.OnSceneLoaded();
}
}
@@ -53,11 +66,23 @@ private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
public void SetSceneLoadingProgressValue(float value)
{
// 여기에 로딩바 UI 연결 예정
}
public void RequestSceneChange(string sceneName)
{
if (_isChangingScene)
{
Debug.Log("이미 씬 전환 중입니다.");
return;
}
if (string.IsNullOrEmpty(sceneName))
{
Debug.LogWarning("이동할 씬 이름이 비어있습니다.");
return;
}
_ = SceneChange(sceneName);
}
@@ -65,35 +90,49 @@ private async Awaitable SceneChange(string sceneName)
{
try
{
//로딩바 수치 0으로 설정
_isChangingScene = true;
// 로딩바 수치 0으로 설정
SetSceneLoadingProgressValue(0f);
if (_loadingRoot != null)
{
_loadingRoot.SetActive(true);
}
AsyncOperation op = SceneManager.LoadSceneAsync(sceneName);
//자동 전환을 하고 싶지 않을 경우 해당값을 false로 두었다가 true로 바꾸면 그 때 전환됨
if (op == null)
{
Debug.LogError($"씬 로드 실패: {sceneName}");
_isChangingScene = false;
return;
}
// 자동 전환을 하고 싶지 않을 경우 false로 두었다가 true로 바꾸면 그 때 전환됨
op.allowSceneActivation = false;
//화면에 보여줄 로딩 수치
// 화면에 보여줄 로딩 수치
float displayProgress = 0f;
//op.progress 0.9가 데이터 로딩이 끝난 기준 allowSceneActivation이 트루면 다음으로 넘어가면서 op.isDone이 true가 된다.
while (op.progress < 0.9f)
// op.progress 0.9가 데이터 로딩이 끝난 기준
while (op.progress < 0.9f)
{
//실제 로딩 수치
// 실제 로딩 수치
float realProgress = Mathf.Clamp01(op.progress / 0.9f);
//보여줄 값을 실제값을 향해 부드럽게 이동
// 보여줄 값을 실제값을 향해 부드럽게 이동
displayProgress = Mathf.MoveTowards(displayProgress, realProgress, Time.deltaTime * 0.5f);
// 로딩바 UI에 값 적용
SetSceneLoadingProgressValue(displayProgress);
//자기자신이 파괴될때 토큰에 취소요청을 보냄
// 자기자신이 파괴될때 토큰에 취소요청을 보냄
await Awaitable.NextFrameAsync(this.destroyCancellationToken);
}
//로딩바 수치 1(100%)로 설정 (데이터 로딩은 이미 끝이기 때문에)
SetSceneLoadingProgressValue(1);
// 로딩바 수치 1(100%)로 설정
SetSceneLoadingProgressValue(1f);
// 잠시 대기했다가 전환
await Awaitable.WaitForSecondsAsync(1.0f, this.destroyCancellationToken);
@@ -102,19 +141,29 @@ private async Awaitable SceneChange(string sceneName)
op.allowSceneActivation = true;
// 씬 활성화가 완전히 끝날 때까지 대기
// allowSceneActivation가 true가 되고 완전히 전환되기까지는 몇프레임 걸림. op.isDone 은 이 과정이 끝난 뒤에 true가 됨.
while(!op.isDone)
while (!op.isDone)
{
await Awaitable.NextFrameAsync(this.destroyCancellationToken);
}
//VR용 로직
//트래킹이 중단되면 안되기 때문에 카메라를 유지해야 한다
_loadingCamTargetTransform = Camera.main.transform; // 새로운 씬의 메인카메라를 따라가게끔 설정
// VR용 로직
// 트래킹이 중단되면 안되기 때문에 카메라를 유지해야 한다
if (Camera.main != null)
{
_loadingCamTargetTransform = Camera.main.transform;
}
if (_loadingRoot != null)
{
_loadingRoot.SetActive(false);
}
_isChangingScene = false;
}
catch (OperationCanceledException)
{
Debug.Log("씬 전환 작업이 취소됨");
_isChangingScene = false;
}
}
}