From e48bb34425c43a30d59ca65cc3305e042a05dc32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20Kr=C3=BCger?= <krueger@vr.rwth-aachen.de> Date: Fri, 11 Jun 2021 11:09:24 +0200 Subject: [PATCH] Add functionality to have enter and leave events on targatable actor --- .../Pawn/BasicVRInteractionComponent.cpp | 29 +++++++++++++++++++ .../Public/Interaction/Targetable.h | 8 +++++ .../Public/Pawn/BasicVRInteractionComponent.h | 4 ++- 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/Source/DisplayClusterExtensions/Private/Pawn/BasicVRInteractionComponent.cpp b/Source/DisplayClusterExtensions/Private/Pawn/BasicVRInteractionComponent.cpp index c0a06d4..fe1a96a 100644 --- a/Source/DisplayClusterExtensions/Private/Pawn/BasicVRInteractionComponent.cpp +++ b/Source/DisplayClusterExtensions/Private/Pawn/BasicVRInteractionComponent.cpp @@ -104,9 +104,38 @@ void UBasicVRInteractionComponent::TickComponent(float DeltaTime, ELevelTick Tic const FTwoVectors StartEnd = GetHandRay(MaxClickDistance); TOptional<FHitResult> Hit = RaytraceForFirstHit(StartEnd); + if (!Hit.IsSet()) + { + + // Execute leave event on the actor that lost the focus if there was one + if (LastActorHit && LastActorHit->Implements<UTargetable>()) + { + ITargetable::Execute_OnTargetedLeave(LastActorHit); + } + + LastActorHit = nullptr; return; + } + AActor* HitActor = Hit->GetActor(); + LastActorHit = HitActor; // Store the actor that was hit to have access to it in the next frame as well + + // Execute Leave and enter events when the focused actor changed + if (HitActor != LastActorHit) + { + //We can always execute the enter event as we are sure that a hit occured + if (HitActor->Implements<UTargetable>()) + { + ITargetable::Execute_OnTargetedEnter(HitActor); + } + + //Only execute the Leave Event if there was an actor that was focused previously + if (LastActorHit != nullptr && LastActorHit->Implements<UTargetable>()) + { + ITargetable::Execute_OnTargetedLeave(LastActorHit); + } + } // for now uses the same distance as clicking if (HitActor->Implements<UTargetable>() && Hit->Distance < MaxClickDistance) diff --git a/Source/DisplayClusterExtensions/Public/Interaction/Targetable.h b/Source/DisplayClusterExtensions/Public/Interaction/Targetable.h index a11da8b..3dd1e6a 100644 --- a/Source/DisplayClusterExtensions/Public/Interaction/Targetable.h +++ b/Source/DisplayClusterExtensions/Public/Interaction/Targetable.h @@ -22,4 +22,12 @@ public: // function that will be called when clickable actor got clicked, and passed the world pos of the click UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = Gameplay) void OnTargeted(FVector WorldPositionOfTarget); + + //function that will be called when a targetable actor gets focused + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = Gameplay) + void OnTargetedEnter(); + + //function that will be called when a targetable actor loses focused + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = Gameplay) + void OnTargetedLeave(); }; diff --git a/Source/DisplayClusterExtensions/Public/Pawn/BasicVRInteractionComponent.h b/Source/DisplayClusterExtensions/Public/Pawn/BasicVRInteractionComponent.h index 6e86c20..bf02488 100644 --- a/Source/DisplayClusterExtensions/Public/Pawn/BasicVRInteractionComponent.h +++ b/Source/DisplayClusterExtensions/Public/Pawn/BasicVRInteractionComponent.h @@ -40,7 +40,9 @@ private: UPROPERTY() UPrimitiveComponent* ComponentSimulatingPhysics = nullptr; UPROPERTY() UGrabbingBehaviorComponent* Behavior = nullptr; UPROPERTY() USceneComponent* InteractionRayEmitter = nullptr; - + UPROPERTY() UStaticMeshComponent* InteractionRay = nullptr; + /* Stores the reference of the Actor that was hit in the last frame*/ + UPROPERTY() AActor* LastActorHit = nullptr; void HandlePhysicsAndAttachActor(AActor* HitActor); FTwoVectors GetHandRay(float Length) const; TOptional<FHitResult> RaytraceForFirstHit(const FTwoVectors& Ray) const; -- GitLab