1. EffectActor에 변수추가
의존성주입은 BP에서함!
UPROPERTY(EditAnywhere,BlueprintReadOnly, Category="Applied Effects")
TSubclassOf<UGameplayEffect> InfiniteGameplayEffectClass;
2. 액터상속받은 FireArea만들고
GE상속받은 FireArea 만듬
2.1 BP에 나이아가라 이펙트 달아주기.
3. GE가서 주기=1초, 체력-5씩 깍이도록 설정, 기간=무한
4. BP에서 내가만든 GE로 의존성 주입!
5. Test
*문제 : 불에서 나가도 체력이 감소함
* 해결 : 기간:무한옵션에서는, 해당효과를 직접 제거해줘야함!
6. 정책설정을 위한 리팩토링
UENUM()
enum class EEffectApplicationPolicy
{
ApplyOnOverlap,
ApplyOnEndOverlap,
DoNotApply
};
UENUM()
enum class EEffectRemovalPolicy
{
RemoveOnEndOverlap,
DoNotRemove
};
UFUNCTION(BlueprintCallable)
void OnOverlap(AActor* TargetActor);
UFUNCTION(BlueprintCallable)
void OnEndOverlap(AActor* TargetActor);
UPROPERTY(EditAnywhere,BlueprintReadOnly, Category="Applied Effects")
bool bDestroyInEffectRemoval = false;
UPROPERTY(EditAnywhere,BlueprintReadOnly, Category="Applied Effects")
TSubclassOf<UGameplayEffect> InstantGameplayEffectClass;
UPROPERTY(EditAnywhere,BlueprintReadOnly, Category="Applied Effects")
EEffectApplicationPolicy InstantEffectApplicationPolicy = EEffectApplicationPolicy::DoNotApply; //기본값
UPROPERTY(EditAnywhere,BlueprintReadOnly, Category="Applied Effects")
TSubclassOf<UGameplayEffect> DurationGameplayEffectClass;
UPROPERTY(EditAnywhere,BlueprintReadOnly, Category="Applied Effects")
EEffectApplicationPolicy DurationEffectApplicationPolicy = EEffectApplicationPolicy::DoNotApply;
UPROPERTY(EditAnywhere,BlueprintReadOnly, Category="Applied Effects")
TSubclassOf<UGameplayEffect> InfiniteGameplayEffectClass;
UPROPERTY(EditAnywhere,BlueprintReadOnly, Category="Applied Effects")
EEffectApplicationPolicy InfiniteEffectApplicationPolicy = EEffectApplicationPolicy::DoNotApply;
UPROPERTY(EditAnywhere,BlueprintReadOnly, Category="Applied Effects")
EEffectRemovalPolicy InfiniteEffectRemovalPolicy = EEffectRemovalPolicy::DoNotRemove;
7. BP에서 정책설정가능
8. 기한이 무한대인경우, 삭제하기위해 맵에 기록을 해둬야한다!
TMap<FActiveGameplayEffectHandle, UAbilitySystemComponent*> ActiveEffectHandles;
void AAuraEffectActor::ApplyEffectToTarget(AActor* TargetActor, TSubclassOf<UGameplayEffect> GameplayEffectClass)
{
...
//GE_BP에서 기간이 무한인지확인
const bool bIsInfinite = EffectSpecHandle.Data.Get()->Def.Get()->DurationPolicy == EGameplayEffectDurationType::Infinite;
if (bIsInfinite && InfiniteEffectRemovalPolicy == EEffectRemovalPolicy::RemoveOnEndOverlap) //오타이슈! (Application -> Removal)
{
ActiveEffectHandles.Add(ActiveEffectHandle, TargetASC); //무한효과를 제거하려면 기록해놔야함!
}
}
아래 부분을 확인하는 코드임
9. 정책에따른 분기 && 제거부분 분석
/정책에 따라 분기
void AAuraEffectActor::OnOverlap(AActor* TargetActor)
{
if(InstantEffectApplicationPolicy==EEffectApplicationPolicy::ApplyOnOverlap)
{
ApplyEffectToTarget(TargetActor, InstantGameplayEffectClass);
}
if(DurationEffectApplicationPolicy==EEffectApplicationPolicy::ApplyOnOverlap)
{
ApplyEffectToTarget(TargetActor, DurationGameplayEffectClass);
}
if(InfiniteEffectApplicationPolicy == EEffectApplicationPolicy::ApplyOnOverlap)
{
ApplyEffectToTarget(TargetActor, InfiniteGameplayEffectClass);
}
}
void AAuraEffectActor::OnEndOverlap(AActor* TargetActor)
{
if(InstantEffectApplicationPolicy==EEffectApplicationPolicy::ApplyOnEndOverlap)
{
ApplyEffectToTarget(TargetActor, InstantGameplayEffectClass);
}
if(DurationEffectApplicationPolicy==EEffectApplicationPolicy::ApplyOnEndOverlap)
{
ApplyEffectToTarget(TargetActor, DurationGameplayEffectClass);
}
if(InfiniteEffectApplicationPolicy == EEffectApplicationPolicy::ApplyOnEndOverlap)
{
ApplyEffectToTarget(TargetActor, InfiniteGameplayEffectClass);
}
if(InfiniteEffectRemovalPolicy==EEffectRemovalPolicy::RemoveOnEndOverlap)
{
UAbilitySystemComponent* TargetASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(TargetActor);
if(!IsValid(TargetASC)) return;
TArray<FActiveGameplayEffectHandle> HandlesToRemove;
for(TTuple<FActiveGameplayEffectHandle, UAbilitySystemComponent*> HandlePair : ActiveEffectHandles)
{
if(TargetASC == HandlePair.Value)
{
//1. 효과제거
TargetASC->RemoveActiveGameplayEffect(HandlePair.Key);
HandlesToRemove.Add(HandlePair.Key); // 2. 제거할 핸들에 추가
}
}
//2. 핸들을 맵에서 제거
for(FActiveGameplayEffectHandle& Handle : HandlesToRemove)
{
ActiveEffectHandles.FindAndRemoveChecked(Handle);
}
}
}
제거정책인경우 :
1. for map 맵에저장되어있는 (key[핸들] 에 대한?) 효과들을 제거한다.
&& 제거할핸들에 저장
2. 핸들자체를 맵에서 제거한다.
+불은 3개까지만 적용되도록 GE설정
+ BP에서는 단순히 onoverlap, endoverlap만 호출하면
cpp에서 정책에의해 분기되서 ApplyEffect가 실행됨
10. 결과
불에서 벗어나면 피가 안깎임.
* 문제 : 겹치는범위에 서있다가 하나라도 벗어나면, 모든스택이 없어짐 -> 불위에있는데 피가 안깍이는 버그
* 해결 : 제거할스택을 1개로설정
기본값 : 모두제거
TargetASC->RemoveActiveGameplayEffect(HandlePair.Key,1);
11. 불더 크게 만들기
박스밑에 niagara추가후 위치,크기를 조정하면됨
12. 결과
'UE5 > GameplayEffect' 카테고리의 다른 글
[UE5] PostGameplayEffect // Data Getter 구현, Qualifier 'const' is only allowed on non-static member functions 오류해결 (0) | 2024.06.02 |
---|---|
[UE5] PreAttributeChange // 체력,마나 min-max 제한하는법 (0) | 2024.06.02 |
[UE5] Stacking // 포션을 한번에 여러개 먹을시 제한설정 (0) | 2024.06.02 |
[UE5] 이펙트 종류 // 즉시 vs (기간,무한) vs 주기, 0.1초마다 마나1씩증가구현 2초동안 (0) | 2024.06.02 |
[UE5] 지속 이펙트 구현 (0) | 2024.06.02 |