RealtimeStyleTransferRuntime/Source/LyraGame/Interaction/Tasks/AbilityTask_GrantNearbyInte...

106 lines
3.9 KiB
C++
Raw Permalink Normal View History

2022-05-23 18:41:30 +00:00
// Copyright Epic Games, Inc. All Rights Reserved.
#include "AbilityTask_GrantNearbyInteraction.h"
2022-09-13 07:18:28 +00:00
#include "Abilities/GameplayAbility.h"
#include "AbilitySystemComponent.h"
#include "CollisionQueryParams.h"
#include "CollisionShape.h"
#include "Containers/Array.h"
#include "Delegates/Delegate.h"
#include "Engine/OverlapResult.h"
#include "Engine/World.h"
2022-05-23 18:41:30 +00:00
#include "GameFramework/Actor.h"
2022-09-13 07:18:28 +00:00
#include "GameFramework/Controller.h"
#include "GameplayAbilitySpec.h"
2022-05-23 18:41:30 +00:00
#include "Interaction/IInteractableTarget.h"
2022-09-13 07:18:28 +00:00
#include "Interaction/InteractionOption.h"
2022-05-23 18:41:30 +00:00
#include "Interaction/InteractionQuery.h"
2022-09-13 07:18:28 +00:00
#include "Interaction/InteractionStatics.h"
#include "Math/Quat.h"
#include "Physics/LyraCollisionChannels.h"
#include "Stats/Stats2.h"
#include "Templates/Casts.h"
#include "Templates/SubclassOf.h"
2022-05-23 18:41:30 +00:00
#include "TimerManager.h"
2022-09-13 07:18:28 +00:00
#include "UObject/ObjectKey.h"
#include "UObject/ScriptInterface.h"
#include "UObject/WeakObjectPtr.h"
#include "UObject/WeakObjectPtrTemplates.h"
2022-05-23 18:41:30 +00:00
UAbilityTask_GrantNearbyInteraction::UAbilityTask_GrantNearbyInteraction(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
}
UAbilityTask_GrantNearbyInteraction* UAbilityTask_GrantNearbyInteraction::GrantAbilitiesForNearbyInteractors(UGameplayAbility* OwningAbility, float InteractionScanRange, float InteractionScanRate)
{
UAbilityTask_GrantNearbyInteraction* MyObj = NewAbilityTask<UAbilityTask_GrantNearbyInteraction>(OwningAbility);
MyObj->InteractionScanRange = InteractionScanRange;
MyObj->InteractionScanRate = InteractionScanRate;
return MyObj;
}
void UAbilityTask_GrantNearbyInteraction::Activate()
{
SetWaitingOnAvatar();
UWorld* World = GetWorld();
World->GetTimerManager().SetTimer(QueryTimerHandle, this, &ThisClass::QueryInteractables, InteractionScanRate, true);
}
void UAbilityTask_GrantNearbyInteraction::OnDestroy(bool AbilityEnded)
{
Super::OnDestroy(AbilityEnded);
UWorld* World = GetWorld();
World->GetTimerManager().ClearTimer(QueryTimerHandle);
}
void UAbilityTask_GrantNearbyInteraction::QueryInteractables()
{
UWorld* World = GetWorld();
AActor* ActorOwner = GetAvatarActor();
if (World && ActorOwner)
{
FCollisionQueryParams Params(SCENE_QUERY_STAT(UAbilityTask_GrantNearbyInteraction), false);
TArray<FOverlapResult> OverlapResults;
World->OverlapMultiByChannel(OUT OverlapResults, ActorOwner->GetActorLocation(), FQuat::Identity, Lyra_TraceChannel_Interaction, FCollisionShape::MakeSphere(InteractionScanRange), Params);
if (OverlapResults.Num() > 0)
{
TArray<TScriptInterface<IInteractableTarget>> InteractableTargets;
UInteractionStatics::AppendInteractableTargetsFromOverlapResults(OverlapResults, OUT InteractableTargets);
FInteractionQuery InteractionQuery;
InteractionQuery.RequestingAvatar = ActorOwner;
InteractionQuery.RequestingController = Cast<AController>(ActorOwner->GetOwner());
TArray<FInteractionOption> Options;
for (TScriptInterface<IInteractableTarget>& InteractiveTarget : InteractableTargets)
{
FInteractionOptionBuilder InteractionBuilder(InteractiveTarget, Options);
InteractiveTarget->GatherInteractionOptions(InteractionQuery, InteractionBuilder);
}
// Check if any of the options need to grant the ability to the user before they can be used.
for (FInteractionOption& Option : Options)
{
if (Option.InteractionAbilityToGrant)
{
// Grant the ability to the GAS, otherwise it won't be able to do whatever the interaction is.
FObjectKey ObjectKey(Option.InteractionAbilityToGrant);
if (!InteractionAbilityCache.Find(ObjectKey))
{
FGameplayAbilitySpec Spec(Option.InteractionAbilityToGrant, 1, INDEX_NONE, this);
FGameplayAbilitySpecHandle Handle = AbilitySystemComponent->GiveAbility(Spec);
InteractionAbilityCache.Add(ObjectKey, Handle);
}
}
}
}
}
}