// Copyright Epic Games, Inc. All Rights Reserved. #include "InteractableInterfaceLibrary.h" // Interaction interface module #include "InteractableTargetInterface.h" #include "InteractionInterfaceLogs.h" // Engine #include "Components/ActorComponent.h" #include "Components/PrimitiveComponent.h" #include "Engine/OverlapResult.h" #include "GameFramework/Actor.h" void UInteractableInterfaceLibrary::GetInteractableTargetsFromActor(AActor* Actor, TArray>& OutInteractionTargets) { TRACE_CPUPROFILER_EVENT_SCOPE(UInteractableInterfaceLibrary::GetInteractableTargetsFromActor); // If the actor is directly interactable, return that. const TScriptInterface InteractableActor(Actor); if (InteractableActor) { OutInteractionTargets.Add(InteractableActor); } // If the actor isn't interactable, it might have a component that has a interactable interface. TArray InteractableComponents = Actor ? Actor->GetComponentsByInterface(UInteractionTarget::StaticClass()) : TArray(); for (UActorComponent* InteractableComponent : InteractableComponents) { OutInteractionTargets.Add(TScriptInterface(InteractableComponent)); } } void UInteractableInterfaceLibrary::AppendTargetConfiguration(TScriptInterface Target, const FInteractionContext& Context, FInteractionQueryResults& OutResults) { if (!Target) { UE_LOG(LogInteractions, Error, TEXT("[%hs] Invalid target! Exiting."), __func__); return; } Target->AppendTargetConfiguration(Context, OutResults); } void UInteractableInterfaceLibrary::BeginInteractionOnTarget(TScriptInterface Target, const FInteractionContext& Context) { if (!Target) { UE_LOG(LogInteractions, Error, TEXT("[%hs] Invalid target! Exiting."), __func__); return; } Target->BeginInteraction(Context); } void UInteractableInterfaceLibrary::ResetQueryResults(UPARAM(ref) FInteractionQueryResults& ToReset) { ToReset.Reset(); } void UInteractableInterfaceLibrary::AppendInteractableTargetsFromOverlapResults(const TArray& OverlapResults, TArray>& OutInteractableTargets) { TRACE_CPUPROFILER_EVENT_SCOPE(UInteractableInterfaceLibrary::AppendInteractableTargetsFromOverlapResults); for (const FOverlapResult& Overlap : OverlapResults) { const TScriptInterface InteractableActor(Overlap.GetActor()); if (InteractableActor) { OutInteractableTargets.AddUnique(InteractableActor); } const TScriptInterface InteractableComponent(Overlap.GetComponent()); if (InteractableComponent) { OutInteractableTargets.AddUnique(InteractableComponent); } } } void UInteractableInterfaceLibrary::AppendInteractableTargetsFromHitResult(const FHitResult& HitResult, TArray>& OutInteractableTargets) { TRACE_CPUPROFILER_EVENT_SCOPE(UInteractableInterfaceLibrary::AppendInteractableTargetsFromHitResult); TScriptInterface InteractableActor(HitResult.GetActor()); if (InteractableActor) { OutInteractableTargets.AddUnique(InteractableActor); } TScriptInterface InteractableComponent(HitResult.GetComponent()); if (InteractableComponent) { OutInteractableTargets.AddUnique(InteractableComponent); } } AActor* UInteractableInterfaceLibrary::GetActorFromInteractableTarget(const TScriptInterface InteractableTarget) { if (UObject* Object = InteractableTarget.GetObject()) { if (AActor* Actor = Cast(Object)) { return Actor; } else if (UActorComponent* ActorComponent = Cast(Object)) { return ActorComponent->GetOwner(); } else { unimplemented(); } } return nullptr; }