본문으로 건너뛰기
Unreal Engine 모듈 · 플러그인 개발LESSON 19

플러그인의 Module 설정과 의존성 설계

난이도심화
예상 시간115분
선수지식17~18강의 Runtime·Editor Plugin 골격

19강. 플러그인의 Module 설정과 의존성 설계

1. 이번 강의에서 해결할 문제​

DataGuardEditor가 ReusableInteraction의 설정을 검사하게 만들 수는 있지만, 반대 방향까지 연결하면 Runtime 빌드가 Editor 코드에 끌려갑니다. 또 .uplugin의 Plugin 의존성과 .Build.cs의 Module 의존성을 같은 것으로 오해하면 Plugin은 활성화되었는데 Header를 찾지 못하거나, 컴파일은 됐는데 로딩 순서에서 실패하는 문제가 생깁니다.

이번 강의에서는 재사용 가능한 낮은 계층에서 선택적 도구 계층으로만 향하는 의존성을 만듭니다.

2. 학습 목표​

3. 핵심 개념​

의존성은 세 층에서 확인해야 합니다.

  1. .uproject 또는 .uplugin은 어떤 Plugin을 사용할지 선언합니다.
  2. .uplugin의 Modules는 Plugin 안의 Module 이름·타입·로딩 시점을 선언합니다.
  3. .Build.cs는 현재 Module이 컴파일과 링크에 필요한 다른 Module을 선언합니다.

Editor 도구가 Runtime API를 읽는 것은 자연스럽습니다. 반대로 Runtime Module이 DataGuardEditor의 타입을 Include하면 Game·Server·Shipping Target에서도 Editor Module이 필요해져 경계가 무너집니다.

4. 단계별 실습​

DataGuard가 ReusableInteraction 설정과 Component를 선택적으로 검사한다고 가정합니다.

DataGuard.uplugin의 일부
{
"FileVersion": 3,
"FriendlyName": "Data Guard",
"Version": 1,
"VersionName": "1.0.0",
"CanContainContent": false,
"Modules": [
{
"Name": "DataGuardEditor",
"Type": "Editor",
"LoadingPhase": "Default"
}
],
"Plugins": [
{
"Name": "ReusableInteraction",
"Enabled": true,
"Optional": true
}
]
}

Optional은 DataGuard 자체를 켜기 위한 절대 조건으로 만들지 않겠다는 배포 정책입니다. 실제 코드에서 Runtime 타입을 무조건 사용한다면 Optional로 두면 안 됩니다. 이 과정에서는 WITH_REUSABLE_INTERACTION 같은 임의 매크로를 만들기보다, 최종 배포본은 명확한 필수 의존으로 고정하거나 두 기능을 분리해 빌드합니다.

DataGuardEditor.Build.cs
using UnrealBuildTool;

public class DataGuardEditor : ModuleRules
{
public DataGuardEditor(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;

PrivateDependencyModuleNames.AddRange(new[]
{
"Core",
"CoreUObject",
"Engine",
"UnrealEd",
"ToolMenus",
"Slate",
"SlateCore",
"DataValidation",
"AssetRegistry",
"ReusableInteraction"
});
}
}

DataGuard의 Public Header가 UInteractionComponent를 멤버 값이나 상속 기반 클래스로 노출하지 않으므로 ReusableInteraction은 Private Dependency입니다. CPP에서만 다음처럼 사용합니다.

Private/Validation/InteractionComponentValidator.cpp
#include "Interaction/InteractionComponent.h"

bool HasInteractionComponent(const AActor* Actor)
{
return IsValid(Actor) &&
Actor->FindComponentByClass<UInteractionComponent>() != nullptr;
}

반대로 Public Header가 다른 Module의 타입을 값 타입·부모 클래스·공개 함수 반환형으로 노출하면 소비 Module도 그 선언을 해석해야 합니다. Forward Declaration으로 충분한 포인터·참조라면 노출을 줄일 수 있지만, 모든 의존성이 자동으로 Private이 되는 것은 아닙니다.

의존 방향을 문서로 고정합니다.

Game Module ───────▶ ReusableInteraction (Runtime)
▲
│ 선택적 검사
DataGuardEditor (Editor) ──┘

금지: ReusableInteraction ─▶ DataGuardEditor

5. 코드가 동작하는 이유​

Unreal Build Tool은 Target에 포함된 Module 그래프를 바탕으로 Include 경로, 전처리 정의, 링크 입력을 구성합니다. Editor Target에서는 DataGuardEditor가 Runtime Module을 소비하지만, Game Target에는 Editor 타입의 DataGuardEditor가 들어가지 않습니다. 따라서 Runtime 플러그인은 편집 도구 없이도 독립적으로 컴파일·실행됩니다.

6. 자주 하는 실수와 해결법​

7. 직접 실습​

8. 이해 점검 질문 3개​

9. 핵심 요약​

MINI QUIZ

플러그인의 Module 설정과 의존성 설계 미니 퀴즈

선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.

0 / 2
  1. 문제 1“플러그인의 Module 설정과 의존성 설계” 기능을 확장하기 좋은 구조로 설명한 것은 무엇인가요?
  2. 문제 2‘Plugin을 Descriptor에만 추가’ 실수를 판단할 때 “플러그인의 Module 설정과 의존성 설계” 강의가 제시한 기준은 무엇인가요?
LESSON STATUS

학습을 마쳤나요?

직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.

19강. 플러그인의 Module 설정과 의존성 설계 미완료 상태