이번 포스트에는 게임에 등장하는 캐릭터별로 레벨을 설정하기 위한 인터페이스를 만들고
이를 실제로 적용해보도록 하겠습니다.
스탯을 결정짓는 레벨의 관리는
플레이어의 경우, PlayerState에서 관리하고
몬스터의 경우 Enemy에서 관리하도록 하겠습니다.
1) CombatInterface
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "UObject/Interface.h"
#include "CombatInterface.generated.h"
// This class does not need to be modified.
UINTERFACE(MinimalAPI)
class UCombatInterface : public UInterface
{
GENERATED_BODY()
};
/**
*
*/
class AURA_API ICombatInterface
{
GENERATED_BODY()
// Add interface functions to this class. This is the class that will be inherited to implement this interface.
public:
virtual int32 GetPlayerLevel() { return 0; }
};
레벨을 반환하기 위한 CombatInterface는 위와 같이 구현되었습니다.
C++에서의 추상 클래스와 인터페이스의 차이점은 정의가 불가능하냐 / 가능하냐의 차이입니다.
인터페이스의 경우, 정의가 가능하므로 만약 오버라이드되지 않는다면 0을 반환하게 됩니다.
2) AuraCharacterBase
모든 캐릭터들의 조상 클래스인 AuraCharacterBase에서 CombatInterface를 상속받도록 하겠습니다.
따라서 해당 클래스를 상속받은 클래스들은 인터페이스의 가상 메서드를 오버라이드할 수 있습니다.
3) AuraEnemy
.
.
.
UCLASS()
class AURA_API AAuraEnemy : public AAuraCharacterBase, public IEnemyInterface
{
.
.
.
/*
* Combat Interface Section
*/
virtual int32 GetPlayerLevel() override { return Level; }
protected:
.
.
.
/*
* Level Section
*/
UPROPERTY(EditAnywhere, Category = "Character Class Defaults")
int32 Level = 1;
};
적의 조상 클래스인 AuraEnemy의 경우, CombatInterface의 메서드를 위와 같이 오버라이드하였습니다.
따라서 몬스터의 고유 레벨을 리턴합니다.
4) 플레이어의 레벨 - AuraPlayerState
.
.
.
UCLASS()
class AURA_API AAuraPlayerState : public APlayerState, public IAbilitySystemInterface
{
GENERATED_BODY()
public:
.
.
.
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
.
.
.
/*
* Level Section
*/
FORCEINLINE int32 GetPlayerLevel() const { return Level; }
.
.
.
private:
/*
* Level Section
*/
UPROPERTY(VisibleAnywhere, ReplicatedUsing = OnRep_Level)
int32 Level = 1;
UFUNCTION()
void OnRep_Level(int32 OldLevel);
};
.
.
.
void AAuraPlayerState::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AAuraPlayerState, Level);
}
.
.
.
PlayerState에 새로운 프로퍼티인 Level을 추가하고,
해당 레벨을 PlayerCharacter에서 사용하기 위해 새로운 Getter 메서드를 만들었습니다.
또한 플레이어의 레벨의 경우 몬스터와 다르게 서버에서만 업데이트가 이뤄지는 것이 아닌,
클라이언트에서 변경되어 업데이트가 이뤄질 수 있으므로 레플리케이션을 위한 로직도 추가하겠습니다.
5) 플레이어의 레벨 - AuraPlayer
.
.
.
UCLASS()
class AURA_API AAuraPlayer : public AAuraCharacterBase
{
GENERATED_BODY()
public:
.
.
.
/*
* Combat Interface Section
*/
virtual int32 GetPlayerLevel() override;
.
.
.
};
.
.
.
int32 AAuraPlayer::GetPlayerLevel()
{
const AAuraPlayerState* AuraPlayerState = GetPlayerState<AAuraPlayerState>();
check(AuraPlayerState);
return AuraPlayerState->GetPlayerLevel();
}
.
.
.
Player의 경우, 레벨이 PlayerState에서 관리되고 있으므로
PlayerState로부터 Getter메서드를 통해 레벨을 리턴할 수 있도록 구성하였습니다.
위와 같이 구성된 레벨은 여러 스탯에 영향을 미칠 수 있도록
이전의 GameplayEffect의 CustomCalculation에 사용할 것입니다.
'언리얼 > 게임 프로젝트' 카테고리의 다른 글
다커 앤 다커 모작 - 8일차_상호작용 #2 (0) | 2025.02.07 |
---|---|
다커 앤 다커 모작 - 8일차_상호작용 #1 (0) | 2025.02.06 |
다커 앤 다커 모작 - 7일차_아이템 #12 (0) | 2025.02.04 |
Lyra 클론코딩 - (13) GameFeature Activate (0) | 2025.01.26 |
Lyra 클론코딩 - (12) Portal UserFacingExpereience Load (0) | 2025.01.26 |