RPG나 액션 게임에서 캐릭터의 성장과 스탯 변화는 플레이어의 몰입도를 크게 좌우한다. 특히 능력치가 다양한 방식으로 결합되고, 아이템이나 스킬에 따라 동적으로 변하는 스탯 시스템은 플레이어가 끊임없이 캐릭터의 발전을 체감할 수 있게 해준다. 그러나 언리얼 엔진에서 고도화된 캐릭터 스탯 시스템을 만드는 것은 쉽지 않다. 단순한 체력이나 공격력 설정을 넘어 복합적인 특성과 아이템, 상태 변화에 따라 스탯을 관리하는 고급 시스템을 설계해야 하기 때문이다. 이 글에서는 언리얼 엔진에서 고도화된 캐릭터 스탯 시스템을 구축하는 방법과, 다양한 상황을 고려한 예제 코드 및 응용 방안을 설명한다.

1. 왜 고도화된 캐릭터 스탯 시스템이 중요한가?

간단한 스탯 시스템은 유지보수가 쉽고 직관적이지만, 플레이어가 원하는 ‘성장감’과 ‘전략성’을 구현하기에는 한계가 있다. 게임이 진행될수록 스탯의 종류나 상호작용이 다양해지며 플레이어가 고유의 특성 조합을 구성할 수 있어야 몰입도가 증가한다. 예를 들어, 특정 아이템이 체력을 증가시키는 동시에 공격력도 변화시킬 수 있다면, 이러한 효과를 데이터와 시스템에 어떻게 반영할 것인지에 대한 세밀한 설계가 필요하다.

2. 고도화된 스탯 시스템의 정의와 주요 기능

고도화된 스탯 시스템은 캐릭터의 기본 능력치 외에 다양한 특성(예: 체력 재생, 치명타 확률)을 포함하고, 상태 변화나 아이템 효과에 따라 실시간으로 스탯을 동적으로 조정할 수 있는 시스템이다. 언리얼 엔진에서 이러한 시스템을 구축하기 위해서는 모듈화데이터 기반 설계가 필수적이다.

주요 기능

  • 스탯에 대한 동적 조정 (아이템, 스킬, 상태 이상 등)
  • 능력치에 따른 스탯의 비율 조정 (레벨에 따라 체력과 공격력의 비율 증가 등)
  • 스탯 간의 상호작용 설정 (예: 치명타 확률이 공격 속도에 영향을 미침)
  • 모듈화된 스탯 구조로 캐릭터 확장 가능

3. 언리얼에서의 고도화된 캐릭터 스탯 시스템 설계와 구현

주요 클래스와 데이터 설계

  • UCharacterStatsComponent: 캐릭터의 스탯을 관리하는 컴포넌트. 체력, 마나, 공격력, 방어력 등의 기본 스탯을 포함하고, 실시간으로 변하는 특성들도 관리한다.
  • StatModifiers: 스탯을 동적으로 변경할 수 있는 요소를 정의한 구조체. 아이템이나 스킬을 통해 증가 또는 감소할 수 있다.
  • DataTable: 각 스탯의 기본값을 정의하는 테이블로, 레벨이나 조건에 따른 스탯 변화를 쉽게 설정할 수 있도록 한다.

예제 코드

  1. 스탯 컴포넌트 구현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을 통해 대량의 스탯 데이터를 효율적으로 관리하고 로드할 수 있어 유지보수가 쉽다.

단점

  • 구현 복잡도 증가: 시스템이 고도화됨에 따라, 데이터 관리 및 동적 변화를 다루는 코드의 복잡성이 크게 증가한다.
  • 성능 문제: 스탯을 실시간으로 업데이트하고 로드하는 과정에서 성능 저하가 발생할 수 있어 최적화가 필요하다.

마무리

언리얼 엔진에서 고도화된 캐릭터 스탯 시스템을 설계하면 플레이어가 각기 다른 특성의 캐릭터를 자유롭게 구성하고 성장시킬 수 있다. 또한 다양한 상황에서 스탯을 동적으로 조정할 수 있어 플레이어의 전략적인 플레이를 지원한다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다