// Copyright Epic Games, Inc. All Rights Reserved. #include "AbilityTask_WaitForInteractableTargets_SingleLineTrace.h" #include "GameFramework/Actor.h" #include "Physics/LyraCollisionChannels.h" #include "Interaction/IInteractableTarget.h" #include "Interaction/InteractionStatics.h" #include "Interaction/InteractionQuery.h" #include "AbilitySystemComponent.h" #include "DrawDebugHelpers.h" #include "Engine/World.h" #include "TimerManager.h" UAbilityTask_WaitForInteractableTargets_SingleLineTrace::UAbilityTask_WaitForInteractableTargets_SingleLineTrace(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { } UAbilityTask_WaitForInteractableTargets_SingleLineTrace* UAbilityTask_WaitForInteractableTargets_SingleLineTrace::WaitForInteractableTargets_SingleLineTrace(UGameplayAbility* OwningAbility, FInteractionQuery InteractionQuery, FCollisionProfileName TraceProfile, FGameplayAbilityTargetingLocationInfo StartLocation, float InteractionScanRange, float InteractionScanRate, bool bShowDebug) { UAbilityTask_WaitForInteractableTargets_SingleLineTrace* MyObj = NewAbilityTask(OwningAbility); MyObj->InteractionScanRange = InteractionScanRange; MyObj->InteractionScanRate = InteractionScanRate; MyObj->StartLocation = StartLocation; MyObj->InteractionQuery = InteractionQuery; MyObj->TraceProfile = TraceProfile; MyObj->bShowDebug = bShowDebug; return MyObj; } void UAbilityTask_WaitForInteractableTargets_SingleLineTrace::Activate() { SetWaitingOnAvatar(); UWorld* World = GetWorld(); World->GetTimerManager().SetTimer(TimerHandle, this, &ThisClass::PerformTrace, InteractionScanRate, true); } void UAbilityTask_WaitForInteractableTargets_SingleLineTrace::OnDestroy(bool AbilityEnded) { Super::OnDestroy(AbilityEnded); UWorld* World = GetWorld(); World->GetTimerManager().ClearTimer(TimerHandle); } void UAbilityTask_WaitForInteractableTargets_SingleLineTrace::PerformTrace() { AActor* AvatarActor = Ability->GetCurrentActorInfo()->AvatarActor.Get(); if (!AvatarActor) { return; } UWorld* World = GetWorld(); TArray ActorsToIgnore; ActorsToIgnore.Add(AvatarActor); const bool bTraceComplex = false; FCollisionQueryParams Params(SCENE_QUERY_STAT(UAbilityTask_WaitForInteractableTargets_SingleLineTrace), bTraceComplex); Params.AddIgnoredActors(ActorsToIgnore); FVector TraceStart = StartLocation.GetTargetingTransform().GetLocation(); FVector TraceEnd; AimWithPlayerController(AvatarActor, Params, TraceStart, InteractionScanRange, OUT TraceEnd); FHitResult OutHitResult; LineTrace(OutHitResult, World, TraceStart, TraceEnd, TraceProfile.Name, Params); TArray> InteractableTargets; UInteractionStatics::AppendInteractableTargetsFromHitResult(OutHitResult, InteractableTargets); UpdateInteractableOptions(InteractionQuery, InteractableTargets); #if ENABLE_DRAW_DEBUG if (bShowDebug) { FColor DebugColor = OutHitResult.bBlockingHit ? FColor::Red : FColor::Green; if (OutHitResult.bBlockingHit) { DrawDebugLine(World, TraceStart, OutHitResult.Location, DebugColor, false, InteractionScanRate); DrawDebugSphere(World, OutHitResult.Location, 5, 16, DebugColor, false, InteractionScanRate); } else { DrawDebugLine(World, TraceStart, TraceEnd, DebugColor, false, InteractionScanRate); } } #endif // ENABLE_DRAW_DEBUG }