데미지를 전달할 GameplayEffect 생성
GameplayEffect를 블루프린트로 상속받아 블루프린트 클래스를 생성한다
현재 기능은 단순히 캐릭터의 공격력 스탯(어트리뷰트)만큼 데미지를 전달하는 기능이기 때문에
Modifirers를 이용한다
좀더 복잡한 계산(방어력 등)이 필요하면 Executions을 이용하면 된다.
Executions는 GameplayEffectExecutionCalculation을 상속받아 구현할 수 있다
모디파이어 설정
- 수정할 어트리뷰트를 선택
- 연산자를 선택
- Magnitude Calculation Type에서 전달할 값을 어떤 방식으로 지정할 것인지 선택한다
여기선 Attribute Based로 선택해 캐릭터의 어트리뷰트(스탯)를 가져온다 - Coefficient 항목에선 전달할 값을 변조(수정)할 수 있다
위에선 커브테이블을 이용해 공격(콤보) 단계(1.0, 1.2, 1.5)가 오를수록 더욱 높은 데미지를 얻을 수 있다
Miscellaneous 항목에서 커브테이블을 만들 수 있다 - Backing Attribute에선 가져올 어트리뷰트를 선택할 수 있다
- Attribute Calculation Type은 Base Value(기본 스탯), Magnitude(기본 스탯 + 추가 스탯), Bouns Magnitude(추가스탯)을 선택하여 어트리뷰트에서 어떤 값을 가져올건지 결정할 수 있다.
PPGA_AttackHitCheck GA에서 GE를 활성화 하여 타겟에 데미지 전달
헤더파일
UPROPERTY(EditAnywhere, Category = "GAS")
TSubclassOf<class UGameplayEffect> AttackDamageEffect;
float CurrentLevel;
- GE를 실행시킬 때 필요한 CurrentLevel, 생성할 GameplayEffect Class 정보를 저장할 변수를 헤더에 선언한다
Cpp파일
void UPPGA_AttackHitCheck::TraceResultCallback(const FGameplayAbilityTargetDataHandle& DataHandle)
{
//#include "AbilitySystemBlueprintLibrary.h" 추가
if (UAbilitySystemBlueprintLibrary::TargetDataHasHitResult(DataHandle, 0))
{
FHitResult HitResult = UAbilitySystemBlueprintLibrary::GetHitResultFromTargetData(DataHandle, 0);
PPGAS_LOG(LogGAS, Log, TEXT("Target %s Detected"), *(HitResult.GetActor()->GetName()));
FGameplayEffectSpecHandle SpecHandle = MakeOutgoingGameplayEffectSpec(AttackDamageEffect, CurrentLevel);
if (SpecHandle.IsValid())
{
ApplyGameplayEffectSpecToTarget(CurrentSpecHandle, CurrentActorInfo, CurrentActivationInfo, SpecHandle, DataHandle);
}
}
bool bReplicateEndAbility = true;
bool bWasCancelled = false;
EndAbility(CurrentSpecHandle, CurrentActorInfo, CurrentActivationInfo, bReplicateEndAbility, bWasCancelled);
}
- 결과 콜백함수 에서 EffectSpecHandle을 통해 GE를 타겟에 적용한다
- FGameplayEffectSpecHandle SpecHandle =
MakeOutgoingGameplayEffectSpec(AttackDamageEffect, CurrentLevel);- GA에서 GE를 실행하려면 GameplayEffectSpecHandle을 생성하여 Handle을 통해 GE를 실행하는 방법이 있다
- MakeOutgoingGameplayEffectSpec 함수로 SpecHandle을 만들 수 있으며
인자로 (생성할 GE 클래스, 현재 레벨 정보)가 들어간다- 추가적으로 GA가 아닌 곳에서 GE를 생성하려면 ASC->MakeOutgoingSpec 함수를 호출 해야 되며
인자가 (생성할 GE 클래스, 현재 레벨 정보, EffectContextHandle)로 추가적으로 EffectContextHandle을 생성하여 넣어줘야 한다
- 추가적으로 GA가 아닌 곳에서 GE를 생성하려면 ASC->MakeOutgoingSpec 함수를 호출 해야 되며
- ApplyGameplayEffectSpecToTarget(CurrentSpecHandle, CurrentActorInfo, CurrentActivationInfo, SpecHandle, DataHandle);
- ApplyGameplayEffectSpecToTarget 함수로 GE를 타겟에 적용한다
- CurrentSpecHandle, CurrentActorInfo, CurrentActivationInfo 변수는 GA에 선언되어 있다
- SpecHandle은 위에서 만들었고, DataHandle은 Overlap 이나 라인스윕 결과를 데이터핸들에 넣은것이다
PPCharacterAttributeSet 에서 데미지 반영
PostGameplayEffectExecute 함수를 상속받아 GE가 실행된후 데미지가 들어오면 데미지를 반영해 준다
PostGameplayEffectExecute
void UPPCharacterAttributeSet::PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data)
{
Super::PostGameplayEffectExecute(Data);
float MinHealth = 0.0f;
//#include "GameplayEffectExtension.h" 추가
//Data에 실행되는 GE스펙, 타겟 ASC, EvaluatedData에 변경되는 어트리뷰트 및 연산자 등이 들어있음
if (Data.EvaluatedData.Attribute == GetHealthAttribute())
{
PPGAS_LOG(LogGAS, Warning, TEXT("Direct Healt Accesss : %f"), GetHealth());
SetHealth(FMath::Clamp(GetHealth(), MinHealth, GetMaxHealth()));
}
else if (Data.EvaluatedData.Attribute == GetDamageAttribute())
{
PPGAS_LOG(LogGAS, Log, TEXT("Direct Healt Accesss : %f"), GetHealth());
SetHealth(FMath::Clamp(GetHealth() - GetDamage(), MinHealth, GetMaxHealth()));
SetDamage(0.0f);
}
}
- const FGameplayEffectModCallbackData& Data
- Data를 사용하려면 #include "GameplayEffectExtension.h" 추가해야 됨
- Super::PostGameplayEffectExecute(Data);
- 부모 로직 실행
- float MinHealth = 0.0f;
- 체력 최솟값 저장
- if (Data.EvaluatedData.Attribute == GetHealthAttribute())
{
PPGAS_LOG(LogGAS, Warning, TEXT("Direct Healt Accesss : %f"), GetHealth());
SetHealth(FMath::Clamp(GetHealth(), MinHealth, GetMaxHealth()));
}- 들어온 데이터의 어트리뷰트가 헬스일 경우 경고 로그 출력
- SetHealth 함수로 체력 반영
- else if (Data.EvaluatedData.Attribute == GetDamageAttribute())
{
PPGAS_LOG(LogGAS, Log, TEXT("Direct Healt Accesss : %f"), GetHealth());
SetHealth(FMath::Clamp(GetHealth() - GetDamage(), MinHealth, GetMaxHealth()));
SetDamage(0.0f);
}- 들어온 데이터의 어티리뷰트 일경우 로그 출력
- SetHealth 함수로 (현재체력 - 들어온 데미지)로 설정 및 Clamp를 범위를 걸어 체력 지정
- SetDamage(0.0)으로 데미지 초기화
'포트폴리오 제작 > Project_P' 카테고리의 다른 글
Project_P 행동트리 모델 생성 (1) | 2024.11.14 |
---|---|
Project_P 체력바 UI 생성 (0) | 2024.10.21 |
Project_P AttributeSet을 캐릭터에 생성하기 (0) | 2024.10.16 |
Project_P AttributeSet을 사용하여 스탯 만들기 (0) | 2024.10.16 |
Project_P 캐릭터에 구현된 Move함수 실행시 GameplayTag 부여 (0) | 2024.10.04 |