UE 5 스터디/Gameplay Ability System(GAS)
24-14. 감전사 스펠 - (8) 구형 범위 이내 근접한 적 찾기
Crat3
2025. 3. 7. 18:49
0. 개요
첫 타격 대상 주위의 다른 적을 감지하여 감전사 스펠이 뻗어 나가도록 구현한다.
1. 체인 라이트닝
(1) AuraBeamSpell 어빌리티에서 멤버 변수와 함수 선언
첫 대상 주위의 다른 적을 감지하고 해당 적들을 배열에 담아, 각 대상에 대해 게임플레이 큐 파라미터를 만들 것이다.
UPROPERTY(EditDefaultsOnly, Category = "Beam")
int32 MaxNumShockTargets = 5;
UFUNCTION(BlueprintCallable)
void StoreAdditionalTarget(TArray<AActor*>& OutAdditionalTargets);
(2) Aura 어빌리티 시스템 라이브러리 - 가장 가까운 타겟 찾기 함수
UFUNCTION(BlueprintCallable, category = "AuraAbilitySystemLibrary|GameplayMechanics")
static void GetClosestTargets(int32 MaxTargets, const TArray<AActor*>& Actors, TArray<AActor*>& OutClosestTargets, const FVector& Origin);
void UAuraAbilitySystemLibrary::GetClosestTargets(int32 MaxTargets, const TArray<AActor*>& Actors, TArray<AActor*>& OutClosestTargets, const FVector& Origin)
{
// 찾으려는 타겟이 대상들보다 많으면 그대로 전달
if (Actors.Num() <= MaxTargets)
{
OutClosestTargets = Actors;
return;
}
TArray<AActor*> ActorsToCheck = Actors;
int32 NumCheck = 0;
while (NumCheck < MaxTargets)
{
if (ActorsToCheck.Num() == 0)
break;
double ClosestDistance = TNumericLimits<double>::Max();
AActor* ClosestActor;
for (AActor* Actor : ActorsToCheck)
{
const double Distance = (Origin - Actor->GetActorLocation()).Length();
if (ClosestDistance > Distance)
{
ClosestDistance = Distance;
ClosestActor = Actor;
}
}
ActorsToCheck.Remove(ClosestActor);
OutClosestTargets.AddUnique(ClosestActor);
NumCheck++;
}
}
배열을 복사하여 원점에서 가장 가까운 거리와 액터를 저장한다.
복사한 배열에서 가장 근접한 액터를 제거하고, 내보낼 배열에 해당 액터를 집어넣는다.
(3) AuraBeamSpell의 근접한 타겟을 배열로 저장하는 함수
void UAuraBeamSpell::StoreAdditionalTarget(TArray<AActor*>& OutAdditionalTargets)
{
TArray<AActor*> ActorsToIgnore;
ActorsToIgnore.Add(GetAvatarActorFromActorInfo());
ActorsToIgnore.Add(MouseHitActor); // 이미 빔에 맞고 있기 때문에 제외
// 구형 오버랩
TArray<AActor*> OverlappingActors;
UAuraAbilitySystemLibrary::GetLivePlayersWithinRadius(
GetAvatarActorFromActorInfo(),
OverlappingActors,
ActorsToIgnore,
850.f, // 탐색 반경
MouseHitActor->GetActorLocation());
// int32 NumAdditionalTargets = FMath::Min(GetAbilityLevel() - 1, MaxNumShockTargets);
int32 NumAdditionalTargets = 5;
// 가장 근접한 대상 찾음
UAuraAbilitySystemLibrary::GetClosestTargets(
NumAdditionalTargets,
OverlappingActors,
OutAdditionalTargets,
MouseHitActor->GetActorLocation());
}
이전에 라이브러리에서 만들었던 함수를 사용하여 구형 쿼리를 실시하고, 해당 범위 내의 살아있는 적을 추적한다.
추적된 액터들 대상으로 마우스 포인트 지점에서 가장 근접한 대상을 찾는다.
(4) GA_Electrocute 이벤트 그래프