관리 메뉴

Mini

[UE5] Infinite이펙트 만들기 // 불에 닿으면 피감소 구현 본문

UE5/GameplayEffect

[UE5] Infinite이펙트 만들기 // 불에 닿으면 피감소 구현

Mini_96 2024. 6. 2. 18:25

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. 결과

 

https://github.com/DongHoonYu96/GameplayAbilitySystem_Aura/commit/0064748b3163e777b8ff2848a76d004476ebbb69

 

feat : 불에닿으면 피감소구현 / 벗어나면 멈춤 · DongHoonYu96/GameplayAbilitySystem_Aura@0064748

Bisu96 committed Jun 2, 2024

github.com