각 속성마다 오류를 피하기 위해 최대값을 지정하는 것도 좋은 방법
어트리뷰트 세트(Attribute Set)
단일 어트리뷰트 데이터인 GameplayAttributeData의 묶음
GameplayAttributeData는 하나의 값이 아닌 두 가지 값으로 구성됨
- BaseValue : 기본 값, 영구적으로 적용되는 고정 스탯 값을 관리
- CurrentValue : 변동 값, 버프 등으로 임시적으로 변동된 값을 관리
PreAttributeChange : 어트리뷰트 변경 전에 호출
PostAttributeChange : 어트리뷰트 변경 후에 호출
PreGameplayEffectExecute : 게임플레이 이펙트 적용 전에 호출
PostGameplayEffectExecute : 게임플레이 이펙트 적용 후에 호출
어트리뷰트 세트 접근자 매크로 : 많이 수행되는 기능에 대해 매크로를 만들어 제공하여 일일이 Get/Set 함수를 선언하지 않아도 됨
#define ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName)
ASC는 초기화될 때 같은 액터에 있는 UAttributeSet 타입 객체를 찾아서 등록하기 때문에 수동으로 등록할 필요가 없음
void UAbilitySystemComponent::InitializeComponent()
{
...
TArray<UObject*> ChildObjects;
GetObjectsWithOuter(Owner, ChildObjects, false, RF_NoFlags, EInternalObjectFlags::Garbage);
for (UObject* Obj : ChildObjects)
{
UAttributeSet* Set = Cast<UAttributeSet>(Obj);
if (Set)
{
SpawnedAttributes.AddUnique(Set);
bIsNetDirty = true;
}
}
...
}
다른 GAS 액터의 정보를 확인할 수 있는 디버그 시스템 설정 방법
DefaultGame.ini 파일에 해당 속성을 true로 변경해야 함
[/Script/GameplayAbilities.AbilitySystemGlobals]
bUseDebugTargetFromHud=True
어트리뷰트 세트를 활용한 공격 판정 관련 구현
FGameplayAbilityTargetDataHandle AABTA_Trace::MakeTargetData() const
{
ACharacter* Character = CastChecked<ACharacter>(SourceActor);
UAbilitySystemComponent* AbilitySystemComponent = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(SourceActor);
if (AbilitySystemComponent == nullptr)
{
return FGameplayAbilityTargetDataHandle();
}
const UABCharacterAttributeSet* AttributeSet = AbilitySystemComponent->GetSet<UABCharacterAttributeSet>();
if (AttributeSet == nullptr)
{
return FGameplayAbilityTargetDataHandle();
}
FHitResult OutHitResult;
const float AttackRange = AttributeSet->GetAttackRange();
const float AttackRadius = AttributeSet->GetAttackRadius();
...
}
UABGA_AttackHitCheck::UABGA_AttackHitCheck()
{
InstancingPolicy = EGameplayAbilityInstancingPolicy::InstancedPerActor;
}
void UABGA_AttackHitCheck::ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData)
{
Super::ActivateAbility(Handle, ActorInfo, ActivationInfo, TriggerEventData);
UABAT_Trace* AttackTraceTask = UABAT_Trace::CreateTask(this, AABTA_Trace::StaticClass());
AttackTraceTask->OnComplete.AddDynamic(this, &ThisClass::OnTraceResultCallback);
AttackTraceTask->ReadyForActivation();
}
void UABGA_AttackHitCheck::OnTraceResultCallback(const FGameplayAbilityTargetDataHandle& TargetDataHandle)
{
if (UAbilitySystemBlueprintLibrary::TargetDataHasHitResult(TargetDataHandle, 0))
{
FHitResult HitResult = UAbilitySystemBlueprintLibrary::GetHitResultFromTargetData(TargetDataHandle, 0);
UAbilitySystemComponent* SourceAbilitySystemComponent = GetAbilitySystemComponentFromActorInfo();
UAbilitySystemComponent* TargetAbilitySystemComponent = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(HitResult.GetActor());
if (SourceAbilitySystemComponent == nullptr || TargetAbilitySystemComponent == nullptr)
{
return;
}
// 원래는 게임플레이 이펙트로 어트리뷰트를 변경해야 하므로 임시로 const_cast 사용
const UABCharacterAttributeSet* SourceAttributeSet = SourceAbilitySystemComponent->GetSet<UABCharacterAttributeSet>();
UABCharacterAttributeSet* TargetAttributeSet = const_cast<UABCharacterAttributeSet*>(TargetAbilitySystemComponent->GetSet<UABCharacterAttributeSet>());
if (SourceAttributeSet == nullptr || TargetAttributeSet == nullptr)
{
return;
}
TargetAttributeSet->SetHealth(TargetAttributeSet->GetHealth() - SourceAttributeSet->GetAttackRate());
}
...
}
void UABCharacterAttributeSet::PreAttributeChange(const FGameplayAttribute& Attribute, float& NewValue)
{
if (Attribute == GetHealthAttribute())
{
NewValue = FMath::Clamp(NewValue, 0.0f, GetMaxHealth());
}
}
'언리얼 > 게임플레이 어빌리티 시스템' 카테고리의 다른 글
언리얼5 게임플레이 이펙트, 큐를 활용한 아이템과 무기 상자 구현 (1) | 2024.12.04 |
---|---|
언리얼5 게임플레이 이펙트를 활용한 어트리뷰트 변경 (2) | 2024.12.02 |
언리얼5 게임플레이 어빌리티를 활용한 공격 판정 시스템 (1) | 2024.11.29 |
언리얼5 게임플레이 어빌리티와 태스크를 활용한 콤보 공격과 점프 (0) | 2024.11.26 |
언리얼5 캐릭터의 게임플레이 어빌리티 시스템 캐릭터 입력 처리 (0) | 2024.11.23 |