RPG나 액션 게임에서 캐릭터의 성장과 스탯 변화는 플레이어의 몰입도를 크게 좌우한다. 특히 능력치가 다양한 방식으로 결합되고, 아이템이나 스킬에 따라 동적으로 변하는 스탯 시스템은 플레이어가 끊임없이 캐릭터의 발전을 체감할 수 있게 해준다. 그러나 언리얼 엔진에서 고도화된 캐릭터 스탯 시스템을 만드는 것은 쉽지 않다. 단순한 체력이나 공격력 설정을 넘어 복합적인 특성과 아이템, 상태 변화에 따라 스탯을 관리하는 고급 시스템을 설계해야 하기 때문이다. 이 글에서는 언리얼 엔진에서 고도화된 캐릭터 스탯 시스템을 구축하는 방법과, 다양한 상황을 고려한 예제 코드 및 응용 방안을 설명한다.
목차
1. 왜 고도화된 캐릭터 스탯 시스템이 중요한가?
간단한 스탯 시스템은 유지보수가 쉽고 직관적이지만, 플레이어가 원하는 ‘성장감’과 ‘전략성’을 구현하기에는 한계가 있다. 게임이 진행될수록 스탯의 종류나 상호작용이 다양해지며 플레이어가 고유의 특성 조합을 구성할 수 있어야 몰입도가 증가한다. 예를 들어, 특정 아이템이 체력을 증가시키는 동시에 공격력도 변화시킬 수 있다면, 이러한 효과를 데이터와 시스템에 어떻게 반영할 것인지에 대한 세밀한 설계가 필요하다.
2. 고도화된 스탯 시스템의 정의와 주요 기능
고도화된 스탯 시스템은 캐릭터의 기본 능력치 외에 다양한 특성(예: 체력 재생, 치명타 확률)을 포함하고, 상태 변화나 아이템 효과에 따라 실시간으로 스탯을 동적으로 조정할 수 있는 시스템이다. 언리얼 엔진에서 이러한 시스템을 구축하기 위해서는 모듈화와 데이터 기반 설계가 필수적이다.
주요 기능
- 스탯에 대한 동적 조정 (아이템, 스킬, 상태 이상 등)
- 능력치에 따른 스탯의 비율 조정 (레벨에 따라 체력과 공격력의 비율 증가 등)
- 스탯 간의 상호작용 설정 (예: 치명타 확률이 공격 속도에 영향을 미침)
- 모듈화된 스탯 구조로 캐릭터 확장 가능
3. 언리얼에서의 고도화된 캐릭터 스탯 시스템 설계와 구현
주요 클래스와 데이터 설계
- UCharacterStatsComponent: 캐릭터의 스탯을 관리하는 컴포넌트. 체력, 마나, 공격력, 방어력 등의 기본 스탯을 포함하고, 실시간으로 변하는 특성들도 관리한다.
- StatModifiers: 스탯을 동적으로 변경할 수 있는 요소를 정의한 구조체. 아이템이나 스킬을 통해 증가 또는 감소할 수 있다.
- DataTable: 각 스탯의 기본값을 정의하는 테이블로, 레벨이나 조건에 따른 스탯 변화를 쉽게 설정할 수 있도록 한다.
예제 코드
- 스탯 컴포넌트 구현
UCharacterStatsComponent
는 각종 스탯을 초기화하고 실시간으로 변경할 수 있도록 구현된다.
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "CharacterStatsComponent.generated.h"
UENUM(BlueprintType)
enum class EStatType : uint8
{
Health,
Mana,
Attack,
Defense,
CriticalRate,
RegenRate
};
USTRUCT(BlueprintType)
struct FStat
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Stat")
float BaseValue;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Stat")
float CurrentValue;
// Modifier로 인한 변동값을 계산
float GetModifiedValue(float Modifier)
{
return CurrentValue + Modifier;
}
};
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class MYGAME_API UCharacterStatsComponent : public UActorComponent
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Stats")
TMap<EStatType, FStat> Stats;
void ModifyStat(EStatType StatType, float Amount);
float GetStatValue(EStatType StatType);
protected:
virtual void BeginPlay() override;
void InitializeStats();
};
스탯 초기화 및 수정 메서드
이 코드에서는 InitializeStats()
로 기본 스탯을 설정하고, ModifyStat()
으로 스탯을 동적으로 변경한다.
void UCharacterStatsComponent::BeginPlay()
{
Super::BeginPlay();
InitializeStats();
}
void UCharacterStatsComponent::InitializeStats()
{
Stats.Add(EStatType::Health, {100.0f, 100.0f});
Stats.Add(EStatType::Mana, {50.0f, 50.0f});
Stats.Add(EStatType::Attack, {10.0f, 10.0f});
Stats.Add(EStatType::Defense, {5.0f, 5.0f});
Stats.Add(EStatType::CriticalRate, {0.05f, 0.05f});
Stats.Add(EStatType::RegenRate, {1.0f, 1.0f});
}
void UCharacterStatsComponent::ModifyStat(EStatType StatType, float Amount)
{
if (Stats.Contains(StatType))
{
Stats[StatType].CurrentValue = FMath::Clamp(Stats[StatType].CurrentValue + Amount, 0.0f, Stats[StatType].BaseValue);
}
}
float UCharacterStatsComponent::GetStatValue(EStatType StatType)
{
return Stats.Contains(StatType) ? Stats[StatType].CurrentValue : 0.0f;
}
아이템과 스킬에 의한 스탯 수정
캐릭터가 특정 아이템을 장착하거나 스킬을 사용할 때, 이 스탯을 동적으로 조정하는 함수를 추가할 수 있다. 예를 들어 ApplyItemModifiers()
는 아이템 효과로 스탯을 변경한다.
void UCharacterStatsComponent::ApplyItemModifiers(const TMap<EStatType, float>& Modifiers)
{
for (const auto& Modifier : Modifiers)
{
ModifyStat(Modifier.Key, Modifier.Value);
}
}
DataTable 활용하기
DataTable을 사용하면 레벨에 따른 스탯 값을 동적으로 로드할 수 있다. 이 DataTable을 이용하면 게임 내에서 여러 레벨에 따른 기본 스탯을 관리할 수 있어 유연성이 높아진다.
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Stats")
UDataTable* StatsTable;
void UCharacterStatsComponent::LoadStatsFromDataTable(int32 Level)
{
if (StatsTable)
{
FStatRow* Row = StatsTable->FindRow<FStatRow>(*FString::FromInt(Level), TEXT(""));
if (Row)
{
Stats[EStatType::Health].BaseValue = Row->Health;
Stats[EStatType::Attack].BaseValue = Row->Attack;
// 다른 스탯들도 마찬가지로 초기화
}
}
}
4. 고도화된 스탯 시스템의 장단점
장점
- 커스터마이징 가능성: 각종 아이템, 스킬 효과에 따른 스탯 변화를 세밀하게 제어할 수 있어 다양한 캐릭터 빌드를 지원한다.
- 성장성 반영: 레벨별로 각기 다른 스탯 증가율을 쉽게 설정할 수 있어 게임의 성장성과 몰입도를 높인다.
- 효율적인 데이터 관리: DataTable을 통해 대량의 스탯 데이터를 효율적으로 관리하고 로드할 수 있어 유지보수가 쉽다.
단점
- 구현 복잡도 증가: 시스템이 고도화됨에 따라, 데이터 관리 및 동적 변화를 다루는 코드의 복잡성이 크게 증가한다.
- 성능 문제: 스탯을 실시간으로 업데이트하고 로드하는 과정에서 성능 저하가 발생할 수 있어 최적화가 필요하다.
마무리
언리얼 엔진에서 고도화된 캐릭터 스탯 시스템을 설계하면 플레이어가 각기 다른 특성의 캐릭터를 자유롭게 구성하고 성장시킬 수 있다. 또한 다양한 상황에서 스탯을 동적으로 조정할 수 있어 플레이어의 전략적인 플레이를 지원한다.