언리얼 C++ 모듈 추가 정리 (Module, Build.cs, ini Config, 비동기 로딩)

언리얼 모듈 학습 노트. 강의 9.6/9.7 개념만. 새 모듈 추가하다 막힐 때 다시 보기.

모듈이란

언리얼 소스코드는 전부 모듈 단위. 모듈 = 소스파일의 빌드 결과물(에디터용 .dll, 실행용 .lib. 예: UnrealEditor-{모듈명}.dll). C++ 프로젝트는 개발자가 직접 모듈을 추가 가능(블루프린트 프로젝트는 불가).

새 모듈 추가 전체 절차 (순서 중요)

  1. Source 폴더에 모듈 폴더 + .Build.cs + .h + .cpp 생성. .cpp에 IMPLEMENT_MODULE
  2. .Target.cs와 Editor.Target.cs에 ExtraModuleNames.Add로 새 모듈 등록(빌드 대상에 포함)
  3. .uproject의 Modules에 새 모듈 추가(에디터가 .dll 로딩하도록)
  4. 모듈에 UObject 클래스가 하나도 없으면 Content Browser에 안 보임 → Object 상속 클래스 하나 만들어 그 모듈에 배치

핵심 함정 — 로딩 순서: 다른 모듈이 의존하는 모듈은 먼저 로드돼야 함. .uproject에서 LoadingPhase를 PreDefault로 두면 Default보다 먼저 로드. 의존 모듈을 PreDefault 안 주면 로드 순서 꼬여서 크래시.

매크로 치트시트:

  • IMPLEMENT_MODULE: 일반 모듈
  • IMPLEMENT_GAME_MODULE: 게임 모듈
  • IMPLEMENT_PRIMARY_GAME_MODULE: 주 게임 모듈. 프로젝트에 하나만

Public vs Private Dependency (자주 헷갈림)

  • 우리 모듈의 .h와 .cpp 모두에서 A 모듈을 쓰면 → PublicDependency. 우리를 참조하는 B 모듈도 A를 알아야 문제 없으므로
  • 우리 모듈의 .cpp에서만 A를 쓰면 → PrivateDependency. B 모듈은 A의 존재를 몰라도 됨

기준: 헤더에 노출되면 Public, 구현에만 숨으면 Private. 무조건 Public에 넣으면 불필요한 의존성이 전파됨.

ini Config로 기본값 설정

코드에 오브젝트 패스를 하드코딩하지 않고 .ini에서 읽어오는 방법:

  • 클래스에 UCLASS(config=파일명), 속성에 UPROPERTY(config)
  • Config 폴더에 Default{파일명}.ini 생성. 엔진 초기화 때 읽어 CDO 기본값으로 채움
  • 배열은 ini에서 +로 누적

장점: 아트팀이 애셋을 옮겨도 ini만 고치면 됨(코드 재빌드 불필요). FSoftObjectPath로 경로를 들고 있다가 필요 시 로드.

애셋 로딩 방식 선택 기준

  • 생성자에서 미리 로딩: 프로젝트 전반에서 필수인 애셋
  • 런타임 동기 로딩: 안 쓸 수도 있지만 쓰기 전 반드시 로드돼야 하는 것
  • 런타임 비동기 로딩: 꼭 미리 로드될 필요 없는 것

비동기 로딩(StreamableManager):

  • FStreamableManager는 프로젝트에 하나만 두는 게 바람직 → AssetManager(GameInstance급 싱글톤)에서 관리. UAssetManager::GetStreamableManager()
  • RequestAsyncLoad에 오브젝트 패스 목록 + FStreamableDelegate 전달 → 로딩 완료 시 델리게이트 호출
  • 델리게이트는 미리 선언해도 되고 CreateLambda로 즉석 생성도 가능. 람다에서 핸들 Release 후 로드된 애셋 사용

함정: 비동기라 콜백 시점에 this/대상이 유효한지 전제. 핸들(FStreamableHandle)을 멤버로 들고 있다가 콜백에서 ReleaseHandle. 핸들을 안 들고 있으면 로딩이 취소될 수 있음.

이 챕터도 관통 패턴은 동일: "완료 시점(로딩 완료, 값 변경)"을 직접 폴링하지 말고 델리게이트로 잡아 다음 동작을 잇는다. 앞 챕터들과 같은 구조.

+ Recent posts