1. Singleton Template
씬을 전환시키는 역할의 클래스를 만들 예정인데, 어디서든 접근 가능하도록 Singleton으로 만들 생각입니다.
https://coding-paper.tistory.com/2
Unity에서의 Singleton 1편 - 싱글턴 클래스 만들기
이 글과 이후 글에서는 싱글턴에 대한 설명보다는 Unity에서 구현해보는데 집중해보고, 문제점과 해결방법을 이야기해볼 예정입니다. 싱글턴에 대한 좀 더 상세하고 원론적인 내용이 필요하신
coding-paper.tistory.com
https://coding-paper.tistory.com/3
Unity에서의 Singleton 2편 - MonoBehaviour Singleton의 문제점
이번에는 MonoBehaviour Singleton을 사용하는 이유 및 문제점을 파악해서 해결 방법을 고민해 볼 겁니다. 사실 Singleton 관련 블로그 글을 써보려고 마음먹은 이유도 이러한 문제점들이 있는데 MonoBeh
coding-paper.tistory.com
이전에 써둔 블로그 글이 있습니다.
사실 이걸 복사해서 만들었습니다.
2. SceneChanger 구현
public void ChangeScene(string sceneName)
{
if (m_CurrentSceneData.IsValid() == true && m_CurrentSceneData.name.Equals(sceneName))
{
Debug.LogError("same scene");
return;
}
m_ChangeTargetSceneName = sceneName;
if (m_IsChangingScene == false)
{
StartCoroutine(ChangeSceneRoutine());
}
}
public IEnumerator ChangeSceneRoutine()
{
// ... //
}
씬을 교체하는 역할을 담당하는 클래스를 Singleton으로 만들었습니다.
현재 사용하는 기능은 ChangeScene정도라 이 부분만 구현해두기로 했습니다.
// 빈 Scene을 호출하여 깔끔하게 다 날려버린다.
async = SceneManager.LoadSceneAsync("EmptyScene", LoadSceneMode.Single);
while(async.isDone == false)
{
m_SceneChangeProgress = 0.0f + async.progress * 0.2f;
yield return null;
}
m_SceneChangeProgress = 0.2f;
// 사용되지 않는 리소스들 언로드
async = Resources.UnloadUnusedAssets();
while(async.isDone == false)
{
m_SceneChangeProgress = 0.2f + async.progress * 0.2f;
yield return null;
}
m_SceneChangeProgress = 0.4f;
// 혹시 모르니 GC도 한번..
System.GC.Collect();
// 본격적으로 씬 로드
m_ChangingSceneName = m_ChangeTargetSceneName;
async = SceneManager.LoadSceneAsync(m_ChangingSceneName, LoadSceneMode.Single);
while(async.isDone == false)
{
m_SceneChangeProgress = 0.4f + async.progress * 0.6f;
yield return null;
}
m_SceneChangeProgress = 1.0f;
// 완료!
m_CurrentSceneData = SceneManager.GetSceneByName(m_ChangingSceneName);
빈 Scene 로드 ▶︎ Unload Unused Assets ▶︎ GC.Collect ▶︎ Scene 로드
위 순서로 진행하도록 구현했습니다.
비어있는 Scene을 굳이 호출해주는 이유는 비어있는 상태에서 UnloadUnusedAssets과 GC.Collect를 호출해주기 위함입니다.
Intro에서 SampleScene으로 넘어가도록 작업해두었습니다.
Hierarchy View에서 Intro, Empty, SampleScene 순서로 넘어가는 걸 볼 수 있습니다.
3. 서브씬 설정 Scriptable Object 만들기
public class SubSceneSetting : ScriptableObject
{
[SerializeField] public List<SubSceneData> SubSceneDatList = new List<SubSceneData>();
[System.Serializable]
public struct SubSceneData
{
[SerializeField] public string sceneName;
[SerializeField] public Vector3 center;
[SerializeField] public float range;
}
#if UNITY_EDITOR
public static SubSceneSetting GenerateSubSceneSetting(string assetName)
{
SubSceneSetting asset = ScriptableObject.CreateInstance<SubSceneSetting>();
UnityEditor.AssetDatabase.CreateAsset(asset, $"Assets/Resources/SubSceneSettings/{assetName}.asset");
UnityEditor.AssetDatabase.SaveAssets();
return asset;
}
#endif
}
간단하게 SubSceneData를 리스트로 들고 있으면 돼서 어렵지 않게 구현했습니다.
문제는 SubSceneData에 무엇이 들어갈 것인가 인데, 일단 위 코드 중심점(center)과 범위(range)로 지정했습니다.

중심점과 범위를 이용하여 해당 영역으로 캐릭터가 들어오거나 카메라가 비춘다거나 하는 경우 서브씬을 로드하도록 구현할 예정입니다.
지금 생각해보면 Radius가 아니라 왜 Range로 이름을 지었는지 모르겠습니다. 다른 방식으로 구현해볼까 고민하다 Radius와 용도가 동일해진 것 같네요.
이 부분에서는 제가 괜찮다 싶은 방법이 떠오르지 않는데, 혹시나 좀 더 괜찮은 방법이 있다면 소개 부탁드립니다.
4. 왜 오늘은 이것밖에 없는가
사실 오늘 KTX타고 고향 내려가는 길에 신나게 코딩했습니다. 물론 repository에 다 남아있죠.
서브씬 관련 작업 · PieceOfPaper/Unity_LinksAwakening@d4e88db
- 서브씬 세팅 관련 기반 구현 - Bundles에 있던 데이터 Resources로 이동
github.com
center, range 값 설정 및 center, range로 그릴지 말지 판단하는 함수들을 이미 다 만들어두었습니다.
다만 오늘 글에 다 남기는 것보다 다음에 작업할 서브씬 설정 툴을 하나씩 기능 구현하면서 설명할까 합니다.
다들 즐거운 추석 되세요.
'개인프로젝트 일지' 카테고리의 다른 글
유니티로 "젤다의 전설: 꿈꾸는 섬" 모작 6일차 (0) | 2022.09.12 |
---|---|
유니티로 "젤다의 전설: 꿈꾸는 섬" 모작 5일차 (2) | 2022.09.10 |
유니티로 "젤다의 전설: 꿈꾸는 섬" 모작 3일차 (0) | 2022.09.08 |
유니티로 "젤다의 전설: 꿈꾸는 섬" 모작 2일차 (0) | 2022.09.04 |
유니티로 "젤다의 전설: 꿈꾸는 섬" 모작 1일차 (0) | 2022.09.03 |