콘텐츠로 이동

UE5 Modular Gameplay Plugin — 게임플레이 기능 분리

Modular Gameplay Plugin은 UE5(Lyra 프로젝트에서 채용)의 게임플레이 기능을 독립 플러그인(GameFeature Plugin)으로 분리하는 아키텍처입니다. 각 기능(무기 시스템, 스킬, 게임 모드)을 독립적으로 활성화/비활성화할 수 있어 DLC, 라이브 서비스, 멀티플레이어 모드 전환에 적합합니다.


Edit → Plugins → Gameplay → ModularGameplay → Enable
Edit → Plugins → Gameplay → GameFeatures → Enable

Tools → New Plugin → Game Feature
Plugin Name: WeaponSystem

생성 구조:

Plugins/GameFeatures/WeaponSystem/
├── WeaponSystem.uplugin
├── Source/WeaponSystem/
└── Content/

.uplugin 설정:

{
"FileVersion": 3,
"Version": 1,
"VersionName": "1.0",
"FriendlyName": "WeaponSystem",
"GameFeatureData": "WeaponSystem/WeaponSystemData.uasset"
}

에디터에서 GameFeatureData 에셋 생성 후 Action 추가:

// C++로 커스텀 GameFeature Action 정의
UCLASS()
class UGameFeatureAction_AddAbilities : public UGameFeatureAction
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere)
TArray<FGameplayAbilitySpec> AbilitiesToAdd;
virtual void OnGameFeatureActivating(
FGameFeatureActivatingContext& Context) override
{
// 플레이어에게 어빌리티 추가
for (auto* Player : Context.GetPlayers())
{
auto* ASC = Player->GetAbilitySystemComponent();
for (auto& Spec : AbilitiesToAdd)
ASC->GiveAbility(Spec);
}
}
virtual void OnGameFeatureDeactivating(
FGameFeatureDeactivatingContext& Context) override
{
// 어빌리티 제거
for (auto* Player : Context.GetPlayers())
{
auto* ASC = Player->GetAbilitySystemComponent();
ASC->ClearAllAbilities();
}
}
};

4. 런타임 GameFeature 활성화/비활성화

섹션 제목: “4. 런타임 GameFeature 활성화/비활성화”
#include "GameFeaturesSubsystem.h"
// GameFeature 활성화
void AMyGameMode::ActivateWeaponSystem()
{
UGameFeaturesSubsystem& Subsystem =
UGameFeaturesSubsystem::Get();
FString PluginURL = TEXT("/WeaponSystem/WeaponSystem.uplugin");
Subsystem.LoadAndActivateGameFeaturePlugin(
PluginURL,
FGameFeaturePluginChangeStateComplete::CreateLambda(
[](const UE::GameFeatures::FResult& Result)
{
if (Result.HasValue())
UE_LOG(LogTemp, Log, TEXT("WeaponSystem 활성화 성공"));
else
UE_LOG(LogTemp, Error, TEXT("활성화 실패: %s"),
*Result.GetError());
}));
}
// GameFeature 비활성화
void AMyGameMode::DeactivateWeaponSystem()
{
FString PluginURL = TEXT("/WeaponSystem/WeaponSystem.uplugin");
UGameFeaturesSubsystem::Get().DeactivateGameFeaturePlugin(
PluginURL, FGameFeaturePluginChangeStateComplete());
}

5. Component 주입 — AddComponents Action

섹션 제목: “5. Component 주입 — AddComponents Action”

에디터의 GameFeatureData에 AddComponents Action 추가:

// GameFeature 활성화 시 지정 Actor에 Component 자동 추가
UCLASS()
class UGameFeatureAction_AddComponents : public UGameFeatureAction
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere)
TSoftClassPtr<UActorComponent> ComponentClass;
UPROPERTY(EditAnywhere)
TSoftClassPtr<AActor> ActorClass; // 대상 Actor 타입
virtual void OnGameFeatureActivating(
FGameFeatureActivatingContext& Context) override
{
// 현재 월드의 해당 Actor 타입에 Component 추가
for (TActorIterator<AActor> It(Context.GetWorld(),
ActorClass.LoadSynchronous()); It; ++It)
{
(*It)->AddComponentByClass(
ComponentClass.LoadSynchronous(), false, FTransform(), false);
}
}
};

Unregistered → Registered → Loaded → Active
↑ |
└──────────── Deactivated ─────────┘
// 현재 상태 확인
EGameFeaturePluginState State =
UGameFeaturesSubsystem::Get().GetPluginState(PluginURL);

Plugins/GameFeatures/
├── ShooterCore/ ← 핵심 FPS 기능
├── ShooterMaps/ ← 맵별 설정
├── TopDownArena/ ← 탑다운 모드
└── PerfTests/ ← 성능 테스트 모드

각 GameFeature는 독립 플러그인으로 필요할 때만 로드됩니다.


Modular Gameplay는 게임플레이 기능을 플러그인 단위로 캡슐화해 코어 게임과 완전히 분리합니다. DLC 기능, 시즌 콘텐츠, 게임 모드 전환을 런타임에 플러그인 활성화/비활성화로 처리할 수 있어 라이브 서비스 게임에 특히 효과적입니다. Lyra 프로젝트를 레퍼런스로 삼아 구조를 파악하면 빠르게 적용할 수 있습니다.