0. 개요
새롭게 생성한 커스텀 게임플레이 이펙트 컨텍스트를 활용할 것이다.
데미지 계산 식에서 블록 또는 크리티컬이 발생할 때 컨텍스트의 불리언을 변경한다.
1. 커스텀 이펙트 컨텍스트 활용
(1) 데미지 계산식 수정 - ExecCalc_Damage
// Block Chance 가져와서 블록이 발생했는지 확인
float TargetBlockChance = 0.f;
ExecutionParams.AttemptCalculateCapturedAttributeMagnitude(DamageStatics().BlockChanceDef, EvalParams, TargetBlockChance);
TargetBlockChance = FMath::Max<float>(TargetBlockChance, 0.f);
const bool bBlocked = FMath::RandRange(1, 100) < TargetBlockChance;
// 불리언 설정
FGameplayEffectContextHandle EffectContextHandle = Spec.GetContext();
FGameplayEffectContext* Context = EffectContextHandle.Get();
FAuraGameplayEffectContext* AuraContext = static_cast<FAuraGameplayEffectContext*>(Context);
AuraContext->SetIsBlockedHit(bBlocked);
// 발생 시 데미지는 절반
if (bBlocked)
{
Damage = Damage / 2.f;
}
이제 게임플레이 이펙트 컨텍스트를 가져와 커스텀 게임플레이 이펙트 컨텍스트로 캐스팅한 뒤 bIsBlocked와 bIsCriticalHit을 활용할 것이다.
(2) 커스텀 어빌리티 시스템 라이브러리 - AuraAbilitySystemLibrary
이제 커스텀 라이브러리를 통해 블루프린트에서 블록과 크리티컬 적중 여부를 가져올 수 있도록 설정한다.
(2-1) Getter
UFUNCTION(BlueprintPure, Category="AuraAbilitySystemLibrary|GameplayEffects")
static bool IsBlockedHit(const FGameplayEffectContextHandle& EffectContextHandle);
UFUNCTION(BlueprintPure, Category = "AuraAbilitySystemLibrary|GameplayEffects")
static bool IsCriticalHit(const FGameplayEffectContextHandle& EffectContextHandle);
bool UAuraAbilitySystemLibrary::IsBlockedHit(const FGameplayEffectContextHandle& EffectContextHandle)
{
// 커스텀 컨텍스트로 캐스팅
if (const FAuraGameplayEffectContext* AuraEffectContext = static_cast<const FAuraGameplayEffectContext*>(EffectContextHandle.Get()))
{
return AuraEffectContext->IsBlockedHit();
}
return false;
}
bool UAuraAbilitySystemLibrary::IsCriticalHit(const FGameplayEffectContextHandle& EffectContextHandle)
{
// 커스텀 컨텍스트로 캐스팅
if (const FAuraGameplayEffectContext* AuraEffectContext = static_cast<const FAuraGameplayEffectContext*>(EffectContextHandle.Get()))
{
return AuraEffectContext->IsCriticalHit();
}
return false;
}
(2-2) Setter
UFUNCTION(BlueprintCallable, category = "AuraAbilitySystemLibrary|GameplayEffects")
// const가 아니면 출력핀이 됨
static void SetIsBlockedHit(UPARAM(ref) FGameplayEffectContextHandle& EffectContextHandle, bool bInIsBlockedHit);
UFUNCTION(BlueprintCallable, category = "AuraAbilitySystemLibrary|GameplayEffects")
// const가 아니면 출력핀이 됨
static void SetIsCriticalHit(UPARAM(ref) FGameplayEffectContextHandle& EffectContextHandle, bool bInIsCriticalHit);
};
non-const 참조를 넘기면 언리얼에서는 자동으로 출력핀으로 설정한다.
해당 참조를 입력핀으로 바꾸기 위해서 UPARAM(ref)를 사용한다.
void UAuraAbilitySystemLibrary::SetIsBlockedHit(FGameplayEffectContextHandle& EffectContextHandle, bool bInIsBlockedHit)
{
// 커스텀 컨텍스트로 캐스팅
if (FAuraGameplayEffectContext* AuraEffectContext = static_cast<FAuraGameplayEffectContext*>(EffectContextHandle.Get()))
{
AuraEffectContext->SetIsBlockedHit(bInIsBlockedHit);
}
}
void UAuraAbilitySystemLibrary::SetIsCriticalHit(FGameplayEffectContextHandle& EffectContextHandle, bool bInIsCriticalHit)
{
// 커스텀 컨텍스트로 캐스팅
if (FAuraGameplayEffectContext* AuraEffectContext = static_cast<FAuraGameplayEffectContext*>(EffectContextHandle.Get()))
{
AuraEffectContext->SetIsCriticalHit(bInIsCriticalHit);
}
}
(3) 데미지 계산식 수정 - ExecCalc_Damage
이제 커스텀 라이브러리를 사용해 코드를 단순화 할 수 있다.
// 불리언 설정
FGameplayEffectContextHandle EffectContextHandle = Spec.GetContext();
UAuraAbilitySystemLibrary::SetIsBlockedHit(EffectContextHandle, bBlocked);
// 최종 크리티컬
float FinalCriticalHitChance = SourceCriticalHitChance - (TargetCriticalHitResistance * CriticalHitResistanceCoefficient);
const bool bCriticalHit = FMath::RandRange(1, 100) < FinalCriticalHitChance;
UAuraAbilitySystemLibrary::SetIsCriticalHit(EffectContextHandle, bCriticalHit);
2. 플로팅 데미지에 색 띄우기 - 사전 작업
private:
// 콜백 데이터에서 꺼내와 구조체에 저장
void SetEffectProperties(const FGameplayEffectModCallbackData & Data, FEffectProperties& Props) const;
void ShowFloatingText(const FEffectProperties& Props, float Damage, bool bBlockedHit, bool bCriticalHit) const;
};
void UAuraAttributeSet::PostGameplayEffectExecute(const FGameplayEffectModCallbackData & Data)
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
else
{
// HitReact 태그 부여
FGameplayTagContainer TagContainer;
TagContainer.AddTag(FAuraGameplayTags::Get().Effects_HitReact);
// 부여된 어빌리티를 찾아서 활성화
Props.TargetASC->TryActivateAbilitiesByTag(TagContainer);
}
const bool bBlock = UAuraAbilitySystemLibrary::IsBlockedHit(Props.EffectContextHandle);
const bool bCriticalHit = UAuraAbilitySystemLibrary::IsCriticalHit(Props.EffectContextHandle);
ShowFloatingText(Props, LocalIncomingDamage, bBlock, bCriticalHit);
}
}
}
발생하는 데미지 위젯 블루프린트에 색을 입히기 위한 사전 작업이다.
'UE 5 스터디 > Gameplay Ability System(GAS)' 카테고리의 다른 글
12-6. UI - (10) 블록, 크리티컬 메세지 띄우기 (0) | 2024.12.26 |
---|---|
12-5. UI - (9) 색이 있는 데미지 텍스트 띄우기 (0) | 2024.12.26 |
12-3. 커스텀 어빌리티 시스템 글로벌(Aura Ability System Globals) (0) | 2024.12.24 |
12-2. 게임플레이 이펙트 컨텍스트 - (2) 구조체 직렬화(Struct Ops Type Traits) (1) | 2024.12.24 |
12-1. 게임플레이 이펙트 컨텍스트 - (1) 커스텀 게임플레이 이펙트 컨텍스트, 직렬화(Serialize) (0) | 2024.12.24 |