diff --git a/Source/DisplayClusterExtensions/Private/Pawn/BasicVRInteractionComponent.cpp b/Source/DisplayClusterExtensions/Private/Pawn/BasicVRInteractionComponent.cpp index c0a06d49cb89fb87288b1246293ce0335f26764d..fe1a96a24f513d4f08cd367632ebf0ee3d31b454 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 a11da8bd223ecfdc4f66863eabc70d71ee5f15e8..3dd1e6a78ec0deb75edfe75ad3a65a82c00eaa35 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 6e86c208e971ad141a34c489bc1d6d3aca123d5c..bf02488dac2b2f033d7d83f0b3f6303a65a4ab0c 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;