이 튜토리얼에서는 Unreal Engine의 GameplayAbility 시스템을 확장하여 RPG 게임 개발에 사용할 수 있는 기본 GameplayAbility 클래스를 생성하는 방법을 알아봅니다.
1. UMyGameplayAbility 클래스 생성
모든 사용자 정의 스킬의 기반이 될 UMyGameplayAbility 클래스를 만듭니다. 이 클래스는 UGameplayAbility를 상속받습니다.
2. UMyGameplayAbility 코드 작성
MyGameplayAbility.h
// RPG 게임 개발을 위한 사용자 정의 GameplayAbility 클래스입니다.
#pragma once
#include "CoreMinimal.h"
#include "Abilities/GameplayAbility.h"
#include "MyGameplayAbility.generated.h"
class UMyAbilitySystemComponent; // 사용자 정의 Ability System Component 참조
// 스킬의 활성화 방식을 정의하는 열거형
UENUM(BlueprintType)
enum class EMyAbilityActivationPolicy : uint8
{
OnTriggered, // 입력 또는 이벤트에 의해 활성화
OnGiven // 캐릭터에게 부여될 때 자동으로 활성화
};
/**
* RPG 게임 개발을 위한 GameplayAbility의 기본 클래스입니다.
*/
UCLASS()
class RPGGAMETEST_API UMyGameplayAbility : public UGameplayAbility
{
GENERATED_BODY()
protected:
// 스킬이 캐릭터에게 부여될 때와 종료될 때 호출되는 메서드를 재정의합니다.
//~ Begin UGameplayAbility Interface.
virtual void OnGiveAbility(const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilitySpec& Spec) override;
virtual void EndAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, bool bReplicateEndAbility, bool bWasCancelled) override;
//~ End UGameplayAbility Interface
// 스킬의 활성화 방식을 설정합니다. 기본값은 OnTriggered입니다.
UPROPERTY(EditDefaultsOnly, Category = "MyAbility")
EMyAbilityActivationPolicy AbilityActivationPolicy = EMyAbilityActivationPolicy::OnTriggered;
// ActorInfo에서 사용자 정의 Ability System Component를 가져오는 함수입니다.
UFUNCTION(BlueprintPure, Category = "MyAbility")
UMyAbilitySystemComponent* GetMyAbilitySystemComponentFromActorInfo() const;
};
MyGameplayAbility.cpp
// 사용자 정의 GameplayAbility 클래스의 구현입니다.
#include "MyGameplayAbility.h"
#include "MyAbilitySystemComponent.h" // 사용자 정의 Ability System Component 헤더 포함
// 스킬이 캐릭터에게 부여될 때 호출됩니다.
void UMyGameplayAbility::OnGiveAbility(const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilitySpec& Spec)
{
Super::OnGiveAbility(ActorInfo, Spec);
// 활성화 정책이 OnGiven이면 스킬을 즉시 활성화합니다.
if (AbilityActivationPolicy == EMyAbilityActivationPolicy::OnGiven)
{
// ActorInfo가 유효하고 스킬이 아직 활성화되지 않았다면 활성화 시도를 합니다.
if (ActorInfo && !Spec.IsActive())
{
ActorInfo->AbilitySystemComponent->TryActivateAbility(Spec.Handle);
}
}
}
// 스킬이 종료될 때 호출됩니다.
void UMyGameplayAbility::EndAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, bool bReplicateEndAbility, bool bWasCancelled)
{
Super::EndAbility(Handle, ActorInfo, ActivationInfo, bReplicateEndAbility, bWasCancelled);
// 활성화 정책이 OnGiven이고 스킬이 종료되었다면, 스킬을 제거합니다.
if (AbilityActivationPolicy == EMyAbilityActivationPolicy::OnGiven)
{
if (ActorInfo)
{
ActorInfo->AbilitySystemComponent->ClearAbility(Handle);
}
}
}
// 현재 액터의 Ability System Component를 사용자 정의 타입으로 캐스팅하여 반환합니다.
UMyAbilitySystemComponent* UMyGameplayAbility::GetMyAbilitySystemComponentFromActorInfo() const
{
// CurrentActorInfo는 UGameplayAbility에서 제공하는 멤버 변수입니다.
return Cast<UMyAbilitySystemComponent>(CurrentActorInfo->AbilitySystemComponent);
}