본문 바로가기

게임프로그래밍/실습2

[실습2] 31. Combat 인터페이스를 통해 플레이어 레벨 얻기

1. 레벨 만들기

 

어트리뷰트들은 레벨에 따라 달라질 수 있다. 그렇기에 이런 레벨을 알 수 있으면 좋은데 레벨을 알기 위해서 계속해서 캐릭터 클래스를 캐스팅 한다면 많은 자원이 소모될 것이다. 그렇기 때문에 인터페이스를 구현하여 인터페이스로 캐스팅 하는 방식을 이용할 것이다.

 

플레이어 스테이트 클래스로 가 이곳에서 레벨을 구현하자.

 

private:
    UPROPERTY(VisibleAnywhere, ReplicatedUsing=OnRep_Level)
    int32 Level = 0;

    UFUNCTION()
    void OnRep_Level(int32 OldLevel);

 

레벨은 물론 서버에서 클라이언트로 복제되어야 할 것이다.

 

virtual void GetLifetimeReplicatedProps(TArray<class FLifetimeProperty>& OutLifetimeProps) const override;
void AAuraPlayerState::GetLifetimeReplicatedProps(TArray<class FLifetimeProperty>& OutLifetimeProps) const
{
    Super::GetLifetimeReplicatedProps(OutLifetimeProps);
    
    DOREPLIFETIME(AAuraPlayerState, Level);    
}

 

아래 매크로는 리플리케이션을 설정하는 매크로이다.

DOREPLIFETIME

 

이제 에너미도 레벨을 설정하자. 플레이어 스테이트는 오로지 플레이어만 가지고 있는 클래스이다.

 

UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Character Class Defaults")
int32 Level = 1;

 

에너미의 레벨은 복제할 필요가 없다. 게임 플레이 중에 에너미를 레벨업 시키거나 레벨을 낮출 일이 없기 때문에 레벨을 복제해서 클라이언트에게 알려줄 필요가 없는 것이다.

 

이제 이 레벨을 불러올 수 있게 구현하자.


2. 컴뱃 인터페이스 만들기

 

이제 인터페이스를 만들어서 각각의 클래스에서 오버라이드 하여 레벨을 불러올 수 있게 해보자.

class PRACTICE2_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 GetLevel();
};

 

레벨을 얻는 함수를 만들어보자. 함수 구현은 그냥 0을 리턴하게 만들었다.

 

이제 베이스 캐릭터 클래스에서 상속을 받으면 된다.

class PRACTICE2_API AAuraCharacterBase : public ACharacter, public IAbilitySystemInterface, public ICombatInterface

 

이제 캐릭터와 에너미 클래스로 가서 함수들을 오버라이드 하자. 베이스 캐릭터에서는 오버라이드 할 필요가 없다.

 

에너미는 그냥 레벨을 리턴하면 되고 플레이어는 플레이어 스테이트에서 이 값을 가져올 수 있어야 할 것이다. 플레이어 스테이트에서 레벨은 프라이빗 멤버 변수이니 게터를 만들도록 하자.

 

게터를 만들었으면 거기서 레벨을 가져와 플레이어 클래스에서 다시 반환해주면 된다.

int32 AAuraCharacter::GetLevel()
{
    AAuraPlayerState* AuraPlayerState = GetPlayerState<AAuraPlayerState>();
    check(AuraPlayerState);
    return AuraPlayerState->GetPlayerLevel();
}

 

이렇게 해서 레벨을 반환하는 함수를 구현하였다.