2023. 3. 12. 21:16ㆍTech/Unity
- 목차
서론
유니티 프로젝트를 보면 Resources폴더나 Plugins폴더 같은 것을 종종 보신 적이 있나요? 유니티에는 특수한 목적을 가진 폴더 이름을 규칙으로 강제를 해놓습니다. 좀 더 순화해서 표현하면 이름을 미리 예약해서 다른 목적으로 사용하지 못하게 하는 것이죠. 코드를 짤 때도 int, include, import 등 예약어들이 있죠. 이런 녀석들은 단독으로 변수의 이름 같은 다른 목적으로 사용할 수 없어요. 예약 폴더명도 마찬가지입니다. 저도 Unity관련 포스팅을 하면서, 예약폴더 같은 것을 자주 언급했던 거 같아요. 오늘은 익숙하게 접하면서 쓰고 있지만, 은근히 신경 쓰지 않는, 하지만 생각보다 중요한 예약 폴더에 대해서 이야기해보려 합니다.
예약 폴더를 지정한 이유?
유니티 엔진단이나 구현된 기능들에서도 특수한 Path를 다루거나 특정 영역의 파일등을 다룰 일이 있습니다. 예시를 하나 세워보겠습니다.
- 유니티 프로젝트에서 사용되는 대부분의 에셋(거의 모든 에셋이죠)은 프로젝트 경로의 /Assets/... 폴더 밑에 저장됩니다.
- Texture, GameObject, AudioClip등 리소스들이 모두 포함됩니다.
- 활성화된 현재 씬에서 존재하지 않는(인스펙터에 캐싱을 한 것도 아닌) 특정 에셋을 스크립트를 통해 Load 하여 사용하려 합니다.
- /Assets/... 하위에 존재하는 특정 에셋을 찾으려 합니다.
이 경우 다음과 같은 조건이 발생합니다.
- 씬에 존재하지 않고, 인스펙터에 캐싱된 것이 아니기 때문에, 메모리상에 아직 올라가 있지 않습니다.
- /Assets/... 하위에는 어떤 경로가 존재할지 모릅니다. 기본적으로 사용자가 자유롭게 경로를 생성/관리할 수 있기 때문입니다.
- 서버 저장소등에서 다운로드하거나 하는 경우가 아니라면 보통은 빌트인 된 리소스중 찾아야 합니다.
- 빌트인된 리소스의 경우는 /Assets/... 의 하위에 존재하고, 참조가 되어있어야 빌듯이 들어갑니다.
- 인스펙터에 캐싱하거나 씬에 올려놓지 않으면 기본적으로 참조가 걸리지 않습니다.
- 런타임에 참조가 되지 않은 오브젝트를 찾는 경우가 발생하는데, 이때 빌드에 리소스가 포함되어있어야 합니다.
- 이 경우, Resource API를 많이 사용합니다.
즉, Resources.Load() 같은 API를 사용하는 상황이라 볼 수 있습니다. Load()의 경우 로드할 에셋의 path와 에셋 타입 등을 지정합니다. 런타임에 A조건을 만족하는 경우에만, Cube라는 오브젝트를 로드해서 보여주려 합니다. Cube는 A조건을 만족하지 않으면 사용하지 않기 때문에, 어떤 씬이나 스크립트 인스펙터에서 캐싱참조를 하지 않고 있습니다. 이 경우, 어느 곳에서도 참조가 걸려 있지 않기 때문에 빌드에는 포함되지 않습니다. 프로젝트에서 Load()에 전달할 path에 존재하긴 하지만, 빌드에는 포함되지 않는 거죠. 그런데 빌드를 뽑아도 Resources.Load()는 런타임에 작동합니다. 왜일까요? 사실은 참조가 안 걸려 있어도 오브젝트가 빌드에 포함되는 걸까요? /Assets/... 하위에 있다면? 모든 오브젝트를 싹 다 빌드에 포함되어야 할까요? 아닙니다. 이래서 필요한 게 Resouces폴더입니다.
서론에서 말했다시피 특수한 목적을 가지고 지정해서 사용하는 게 예약 폴더들입니다. 유니티 공식 문서에서는 특수 폴더라고 부르고 있네요. 이 상황에서 특수 목적은 뭘까요? /Assets/... 의 하위에 존재하며, 참조가 없더라도 빌드에 포함되어 런타임에 Load가 가능할 수 있어야 한다가 되겠네요. Resources폴더 이외의 다른 예약 폴더도 이런 특수 목적을 가지고 있습니다.
예약 폴더들
Assets
유니티 프로젝트의 최상위 폴더인 Assets폴더도 예약 폴더입니다. 대부분의 Path기반 작동은 해당 폴더의 아래 있다는 가정하에 작동합니다. 그래서 생략되어 따로 경로를 알려줄 필요가 없습니다.(단 AssetDatabass의 특정 함수의 경우에는 명시적으로 알려줘야 합니다) 유니티 프로젝트의 탐색기(Project tab)에 표시되려면 Assets폴더의 하위에 있어야 합니다.
Packages
유니티 프로젝트에 포함되는 Package들(UPM에서 설치된)이 위치하는 폴더입니다. Project tab에서 확인이 가능합니다. 프로젝트 폴더를 탐색기에서 Packages폴더를 확인하면 manifest.json과 packages-lock.json파일만 존재합니다. 해당 파일에 기재된 패키지와 버전으로 캐시 된 것들을 참조해서 표시해 줍니다. 패키지들의 Assets폴더 같은 거라 생각하시면 편합니다.
Resources
가장 친숙한 예약 폴더일 수 있습니다. 참조가 걸리지 않은 에셋을 런타임등에 Load 하여 사용하려면 빌듯이 포함되어 있어야 합니다. 해당 폴더의 하위에 존재하는 모든 에셋은 참조와 상관없이 항상 빌드에 포힘 되며 실행 시 참조 그래프 형식으로 순회하여 인덱스를 생성합니다. 그래서 해당 폴더에 에셋이 많이 존재할수록 빌드의 실행 속도가 늦어지는 현상이 발생합니다. 빌드에 반드시 포함되기 때문에, 용량 상승과도 큰 관계가 있습니다.
Plugins
Unity의 기능을 확장하거나 OS에서만 제공하는 기능을 사용하기 위하여 C/C++ dll이나. aar 등을 포함하는 경우가 있습니다. 해당 폴더의 하위에 존재하는 경우 타깃 플랫폼에 따라 분기하여 빌듯이 포함시킬 수 있습니다.
ex) /Plugins/iOS/~ 에 존재하는 플러그인들의 경우 iOS빌드 시에만 포함됩니다.
Editor
Runtime이 아닌 오직 Editor에서만 스크립트들이 있습니다. UnityEditor의 Window들과 관련된 API가 예시로 들 수 있습니다. 이러한 것들은 다른 경로와 구분할 필요가 있습니다. Runtime시나 빌드에는 포함되지 않아야 하기 때문입니다. Editor에서 사용되는 스크립트는 해당 폴더 하위에 존재해야 합니다.
Editor Default Resources
Editor관련 API를 사용할 때도 Resources폴더에서 Load 하듯이, 즉시 반영하여 에셋을 사용해야 하는 경우가 있습니다. 이때 EditorGUIUtility.Load함수를 사용하는데 해당 폴더에 위치한 에셋만 접근 가능합니다. 해당 폴더는 Assets폴더 바로 안 프로젝트의 루트에 위치해야 합니다.
Gizmos
에디터의 Scene view에 그래픽스적으로 보여주는 것을 구현하는 경우가 있습니다. 특정 아이콘등이 이에 해당됩니다. 이러한 리소스를 해당 폴더의 하위에 위치해야 합니다. 이 역시도 Assets폴더에 있는 각 프로젝트 폴더들의 루트에 위치해야 합니다.
Standard Assets
스크립트들은 컴파일 순서가 있습니다. 해당 폴더의 하위에 존재하는 스크립트 파일들은 가장 먼저 컴파일됩니다. 해당 폴더는 하나만 존재해야 합니다. Pro Standard Assets폴더는 Unity의 Pro버전에서만 의미를 가집니다.
Streaming Assets
Resources폴더에 있는 에셋들은 빌드에 반드시 포함됩니다. 해당 폴더의 에셋들도 빌드에 반드시 포함됩니다. 단지 원본 그대로 존재해야 하는 경우가 있습니다. 특정 플랫폼에 최적화된 영상 타입이 그러합니다.
Hidden Assets
임포트의 과정에서 아래의 경우 Assets폴더의 하위에 있다고 하더라도 Unity에서 무시하는 경우가 있습니다.
- 숨긴 폴더
- '.'으로 시작하는 파일이나 폴더
- '~'으로 시작하는 파일이나 폴더
- 'csv'라는 이름을 가진 파일이나 폴더
- .tmp 확장자 파일
마치며
글의 분량을 보니 Resources폴더에 관련된 작동 과정이나 설명이 대부분이었네요. 이러한 예약폴더들을 잘 알고 있어 프로젝트 파일 구조를 관리할 때 유의해서 사용해야 할 거 같습니다.
'Tech > Unity' 카테고리의 다른 글
[Unity]Device simulator(디바이스 시뮬레이터) (0) | 2023.03.04 |
---|---|
[Unity]Unity의 il2cpp (0) | 2022.08.09 |
[Unity]Unity의 Mono (0) | 2022.08.09 |
[Unity]Addressable asset system 원격 환경 적용 법(+ 간단한 응용) (3) | 2022.06.12 |
[Unity]Addressable asset 기본 개념 (2) | 2022.06.12 |