02. Project Setup
이 문서의 목표
설치 방법이 아니라 "왜 이렇게 구성하는가"를 이해한다. 설치 절차 자체는 getting-started.md를 따른다.
왜 RootScope가 필요한가
Framework의 모든 System은 VContainer DI로 등록/주입된다. RootScope는 그 등록의 단일 진입점이다.
RootScope가 없으면 각 System을 어디서 생성하고 언제 초기화할지가 프로젝트마다 제각각이 되어 구조가 붕괴된다.
RootBootstrap.Initialize()가 [RuntimeInitializeOnLoadMethod(BeforeSceneLoad)]로 자동 실행되어 Resources/RootScope.prefab을 로드하고 DontDestroyOnLoad로 유지하는 것도 같은 이유다 - 씬마다 초기화 코드를 반복하지 않기 위함이다.
Addressables를 왜 설정하는가
Framework는 Resources.Load 직접 사용을 금지한다 (Rules #14). 대신 AssetSystem을 통해 Addressables로 로드한다.
이유: 빌드 크기 제어, 비동기 로드, 런타임 교체(패치/DLC) 가능성 때문이다. Addressables Group/Key를 먼저 구성해야 _asset.LoadAsync<T>(key)가 동작한다.
Config는 왜 필요한가
게임 밸런스/설정 데이터를 코드에 하드코딩하면 매직 스트링/매직 넘버가 되어 유지보수가 어려워진다.
Config는 _asset.LoadConfigAsync<T>()로 로드하는 ScriptableObject 성격의 데이터로, 코드와 데이터를 분리한다.
프로젝트를 어떻게 구성하는가
Game 코드는 _Framework와 분리된 Assets/Game 하위에 둔다. 구체적 구조는 03_Project_Structure.md 참고.
실제 사용 예
[Inject] private IAssetSystem _asset;
var result = await _asset.LoadConfigAsync<EnemyConfig>("EnemyConfig");
Best Practice
- RootScope.prefab은 직접 구조를 바꾸지 말고
Configure()끝부분에 게임 전용 System만 추가 등록한다. - Addressables Key는 상수(
AddressableKeys)로 관리하고 문자열을 코드에 흩어놓지 않는다.
자주 하는 실수
- RootScope를 씬마다 새로 배치 (자동 초기화이므로 불필요)
- Addressables 대신 Resources.Load 사용
실습 과제
RootScope.prefab을 열어Configure()흐름을 확인한다.- 임의의 GameObject 하나를 Addressable로 등록하고
LoadAsync로 불러온다.
이전 문서 / 다음 문서
이전: 01_Framework_Architecture.md 다음: 03_Project_Structure.md
관련 Sample
Samples/Asset/AssetSystemSample.cs, Samples/Core/CoreSample.cs
관련 API
Asset.LoadAsync, Asset.LoadConfigAsync (MCP_Index.md Asset 섹션)