diff --git a/Config/DefaultRWTHVRToolkit.ini b/Config/DefaultRWTHVRToolkit.ini index 29ee91a7aaabc28feebf6357b1672bdd652ff613..13066ebe26e8ab454486f97bbb982275d9b2587c 100644 --- a/Config/DefaultRWTHVRToolkit.ini +++ b/Config/DefaultRWTHVRToolkit.ini @@ -4,4 +4,18 @@ +StructRedirects = (OldName="/Script/RWTHVRToolkit.VRTransformRep",NewName="/Script/RWTHVRToolkit.ReplicatedTransform") +ClassRedirects = (OldName="/Script/RWTHVRToolkit.VRWidgetInteractionComponent",NewName="/Script/RWTHVRToolkit.RWTHVRWidgetInteractionComponent") +PropertyRedirects = (OldName="/Script/RWTHVRToolkit.RWTHVRPawn.PawnMovement",NewName="/Script/RWTHVRToolkit.RWTHVRPawn.CollisionHandlingMovement") -+PropertyRedirects = (OldName="/Script/RWTHVRToolkit.RWTHVRPawn.PawnMovement",NewName="/Script/RWTHVRToolkit.RWTHVRPawn.CollisionHandlingMovement") \ No newline at end of file ++PropertyRedirects = (OldName="/Script/RWTHVRToolkit.RWTHVRPawn.PawnMovement",NewName="/Script/RWTHVRToolkit.RWTHVRPawn.CollisionHandlingMovement") ++ClassRedirects = (OldName="/Script/RWTHVRToolkit.RaycastSelectionComponent",NewName="/Script/RWTHVRToolkit.RaycastInteractionComponent") ++ClassRedirects = (OldName="/Script/RWTHVRToolkit.GrabComponent",NewName="/Script/RWTHVRToolkit.DirectInteractionComponent") ++FunctionRedirects = (OldName="/Script/RWTHVRToolkit.RaycastInteractionComponent.OnBeginSelect",NewName="/Script/RWTHVRToolkit.RaycastInteractionComponent.OnBeginInteraction") ++FunctionRedirects = (OldName="/Script/RWTHVRToolkit.RaycastInteractionComponent.OnEndSelect",NewName="/Script/RWTHVRToolkit.RaycastInteractionComponent.OnEndInteraction") ++PropertyRedirects = (OldName="/Script/RWTHVRToolkit.RaycastInteractionComponent.RayCastSelectInputAction",NewName="/Script/RWTHVRToolkit.RaycastInteractionComponent.RayCastInteractionInputAction") ++PropertyRedirects = (OldName="/Script/RWTHVRToolkit.RaycastInteractionComponent.RayCastInteractionInputAction",NewName="/Script/RWTHVRToolkit.RaycastInteractionComponent.InteractionInputAction") ++PropertyRedirects = (OldName="/Script/RWTHVRToolkit.DirectInteractionComponent.PreviousGrabbablesInRange",NewName="/Script/RWTHVRToolkit.DirectInteractionComponent.PreviousInteractableComponentsInRange") ++PropertyRedirects = (OldName="/Script/RWTHVRToolkit.DirectInteractionComponent.GrabInputAction",NewName="/Script/RWTHVRToolkit.DirectInteractionComponent.InteractionInputAction") ++PropertyRedirects = (OldName="/Script/RWTHVRToolkit.DirectInteractionComponent.GrabSphereRadius",NewName="/Script/RWTHVRToolkit.DirectInteractionComponent.InteractionSphereRadius") ++PropertyRedirects = (OldName="/Script/RWTHVRToolkit.DirectInteractionComponent.bOnlyGrabClosestActor",NewName="/Script/RWTHVRToolkit.DirectInteractionComponent.bOnlyInteractWithClosestActor") ++FunctionRedirects = (OldName="/Script/RWTHVRToolkit.DirectInteractionComponent.OnBeginGrab",NewName="/Script/RWTHVRToolkit.DirectInteractionComponent.OnBeginInteraction") ++FunctionRedirects = (OldName="/Script/RWTHVRToolkit.DirectInteractionComponent.OnEndGrab",NewName="/Script/RWTHVRToolkit.DirectInteractionComponent.OnEndInteraction") ++PropertyRedirects = (OldName="/Script/RWTHVRToolkit.DirectInteractionComponent.PreviousGrabBehavioursInRange",NewName="/Script/RWTHVRToolkit.DirectInteractionComponent.PreviousInteractableComponentsInRange") ++PropertyRedirects = (OldName="/Script/RWTHVRToolkit.DirectInteractionComponent.CurrentGrabBehavioursInRange",NewName="/Script/RWTHVRToolkit.DirectInteractionComponent.CurrentInteractableComponentsInRange") \ No newline at end of file diff --git a/Content/Components/DirectInteraction/BP_DirectInteractionComponent.uasset b/Content/Components/DirectInteraction/BP_DirectInteractionComponent.uasset new file mode 100644 index 0000000000000000000000000000000000000000..420322a7da6732a5a5112d5341778debeceff2ef Binary files /dev/null and b/Content/Components/DirectInteraction/BP_DirectInteractionComponent.uasset differ diff --git a/Content/Components/DirectInteraction/IA_DirectInteractionLeft.uasset b/Content/Components/DirectInteraction/IA_DirectInteractionLeft.uasset new file mode 100644 index 0000000000000000000000000000000000000000..05597e706243b8138bcea4da36fcc87849b6ba51 Binary files /dev/null and b/Content/Components/DirectInteraction/IA_DirectInteractionLeft.uasset differ diff --git a/Content/Components/DirectInteraction/IA_DirectInteractionRight.uasset b/Content/Components/DirectInteraction/IA_DirectInteractionRight.uasset new file mode 100644 index 0000000000000000000000000000000000000000..76128dfe613f4825b57d9a27ac9c93e1829554de Binary files /dev/null and b/Content/Components/DirectInteraction/IA_DirectInteractionRight.uasset differ diff --git a/Content/Components/Grabbing/BP_GrabComponent.uasset b/Content/Components/Grabbing/BP_GrabComponent.uasset deleted file mode 100644 index 40c5437d25b66fce44d8073ff8f40103941f70bd..0000000000000000000000000000000000000000 Binary files a/Content/Components/Grabbing/BP_GrabComponent.uasset and /dev/null differ diff --git a/Content/Components/Grabbing/IA_GrabLeft.uasset b/Content/Components/Grabbing/IA_GrabLeft.uasset deleted file mode 100644 index bcc873bcdbf823add969db4e7528603617badb84..0000000000000000000000000000000000000000 Binary files a/Content/Components/Grabbing/IA_GrabLeft.uasset and /dev/null differ diff --git a/Content/Components/Grabbing/IA_GrabRight.uasset b/Content/Components/Grabbing/IA_GrabRight.uasset deleted file mode 100644 index 9df17caed4d5b4f6e8da91e219ffde3fdb72c21e..0000000000000000000000000000000000000000 Binary files a/Content/Components/Grabbing/IA_GrabRight.uasset and /dev/null differ diff --git a/Content/Components/Raycast/BP_RaycastSelectionComponent.uasset b/Content/Components/Raycast/BP_RaycastSelectionComponent.uasset deleted file mode 100644 index 8b06b970f91a7b78d47d15123f69c62cfaab798f..0000000000000000000000000000000000000000 Binary files a/Content/Components/Raycast/BP_RaycastSelectionComponent.uasset and /dev/null differ diff --git a/Content/Components/Raycast/IA_RaycastSelectLeft.uasset b/Content/Components/Raycast/IA_RaycastSelectLeft.uasset deleted file mode 100644 index 16139611e6a786a71823592bd78c1feb2518862d..0000000000000000000000000000000000000000 Binary files a/Content/Components/Raycast/IA_RaycastSelectLeft.uasset and /dev/null differ diff --git a/Content/Components/Raycast/IA_RaycastSelectRight.uasset b/Content/Components/Raycast/IA_RaycastSelectRight.uasset deleted file mode 100644 index 201c652c77e03a56b9c67e9fcfce356d16e10f3c..0000000000000000000000000000000000000000 Binary files a/Content/Components/Raycast/IA_RaycastSelectRight.uasset and /dev/null differ diff --git a/Content/Components/RaycastInteraction/BP_RaycastInteractionComponent.uasset b/Content/Components/RaycastInteraction/BP_RaycastInteractionComponent.uasset new file mode 100644 index 0000000000000000000000000000000000000000..2416ad8fba677355d3d0f1fc8a1708b90bc8fb12 Binary files /dev/null and b/Content/Components/RaycastInteraction/BP_RaycastInteractionComponent.uasset differ diff --git a/Content/Components/RaycastInteraction/IA_RaycastInteractionLeft.uasset b/Content/Components/RaycastInteraction/IA_RaycastInteractionLeft.uasset new file mode 100644 index 0000000000000000000000000000000000000000..13494f735ac48c8c86551b18695f3a0cd064d524 Binary files /dev/null and b/Content/Components/RaycastInteraction/IA_RaycastInteractionLeft.uasset differ diff --git a/Content/Components/RaycastInteraction/IA_RaycastInteractionRight.uasset b/Content/Components/RaycastInteraction/IA_RaycastInteractionRight.uasset new file mode 100644 index 0000000000000000000000000000000000000000..f6ffa30dcc98699d57b19eacfa02bd0701e076e0 Binary files /dev/null and b/Content/Components/RaycastInteraction/IA_RaycastInteractionRight.uasset differ diff --git a/Content/Input/Default_IMC/IMC_General.uasset b/Content/Input/Default_IMC/IMC_General.uasset index a7b024c34a921c006210c9e64c268f05237c21cd..22686d822ccd6f948acca7c5bef8168d983eef4f 100644 Binary files a/Content/Input/Default_IMC/IMC_General.uasset and b/Content/Input/Default_IMC/IMC_General.uasset differ diff --git a/Content/Pawn/BP_RWTHVRPawn_Default.uasset b/Content/Pawn/BP_RWTHVRPawn_Default.uasset index 9531919e30f6d97207deeb2364f67332592dafce..d23d6e88539254ea147fd7a57122d74208f84f86 100644 Binary files a/Content/Pawn/BP_RWTHVRPawn_Default.uasset and b/Content/Pawn/BP_RWTHVRPawn_Default.uasset differ diff --git a/Source/RWTHVRToolkit/Private/Interaction/Interactors/DirectInteractionComponent.cpp b/Source/RWTHVRToolkit/Private/Interaction/Interactors/DirectInteractionComponent.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c8cf9ce35e45d0bc107cd73da08333ef5ba5b2d9 --- /dev/null +++ b/Source/RWTHVRToolkit/Private/Interaction/Interactors/DirectInteractionComponent.cpp @@ -0,0 +1,185 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "Interaction/Interactors/DirectInteractionComponent.h" + +#include "EnhancedInputComponent.h" +#include "Interaction/Interactables/InteractableComponent.h" +#include "Interaction/Interactables/InteractionBitSet.h" + +#include "Kismet/GameplayStatics.h" +#include "Logging/StructuredLog.h" +#include "Utility/RWTHVRUtilities.h" + +// Sets default values for this component's properties +UDirectInteractionComponent::UDirectInteractionComponent() +{ + // Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these + // features off to improve performance if you don't need them. + PrimaryComponentTick.bCanEverTick = true; + // ... +} + +void UDirectInteractionComponent::TickComponent(float DeltaTime, ELevelTick TickType, + FActorComponentTickFunction* ThisTickFunction) +{ + Super::TickComponent(DeltaTime, TickType, ThisTickFunction); + + TArray<UInteractableComponent*> CurrentInteractableCompsInRange; + + TArray<FHitResult> OutHits; + const ETraceTypeQuery TraceType = UEngineTypes::ConvertToTraceType(ECollisionChannel::ECC_PhysicsBody); + + auto DebugTrace = bShowDebugTrace ? EDrawDebugTrace::ForOneFrame : EDrawDebugTrace::None; + + UKismetSystemLibrary::SphereTraceMulti(GetWorld(), GetAttachParent()->GetComponentLocation(), + GetAttachParent()->GetComponentLocation(), InteractionSphereRadius, + TraceType, true, ActorsToIgnore, DebugTrace, OutHits, true, FColor::Green); + + for (FHitResult Hit : OutHits) + { + AActor* HitActor = Hit.GetActor(); + if (HitActor) + { + UInteractableComponent* InteractableComp = SearchForInteractable(HitActor); + if (InteractableComp && InteractableComp->HasInteractionTypeFlag(EInteractorType::Direct) && + InteractableComp->IsInteractable) + { + InteractableComp->HitResult = Hit; + CurrentInteractableCompsInRange.AddUnique(InteractableComp); + } + } + } + + CurrentInteractableComponentsInRange = CurrentInteractableCompsInRange; + + // Call hover start events on all components that were not in range before + for (UInteractableComponent* CurrentInteractableComp : CurrentInteractableCompsInRange) + { + if (!PreviousInteractableComponentsInRange.Contains(CurrentInteractableComp)) + { + PreviousInteractableComponentsInRange.AddUnique(CurrentInteractableComp); + CurrentInteractableComp->HandleOnHoverStartEvents(this, EInteractorType::Direct); + } + } + + TArray<UInteractableComponent*> ComponentsToRemove; + + // Call hover end events on all components that were previously in range, but not anymore + for (UInteractableComponent* PrevInteractableComp : PreviousInteractableComponentsInRange) + { + if (!CurrentInteractableCompsInRange.Contains(PrevInteractableComp)) + { + ComponentsToRemove.AddUnique(PrevInteractableComp); + PrevInteractableComp->HandleOnHoverEndEvents(this, EInteractorType::Direct); + } + } + + for (UInteractableComponent* CompToRemove : ComponentsToRemove) + { + PreviousInteractableComponentsInRange.Remove(CompToRemove); + } +} + +void UDirectInteractionComponent::SetupPlayerInput(UInputComponent* PlayerInputComponent) +{ + IInputExtensionInterface::SetupPlayerInput(PlayerInputComponent); + + const APawn* Pawn = Cast<APawn>(GetOwner()); + if (!Pawn) + return; + + // Probably not the best place to add this. + ActorsToIgnore.AddUnique(GetOwner()); + + UEnhancedInputComponent* EI = Cast<UEnhancedInputComponent>(Pawn->InputComponent); + if (EI == nullptr) + return; + + EI->BindAction(InteractionInputAction, ETriggerEvent::Started, this, + &UDirectInteractionComponent::OnBeginInteraction); + EI->BindAction(InteractionInputAction, ETriggerEvent::Completed, this, + &UDirectInteractionComponent::OnEndInteraction); +} + +void UDirectInteractionComponent::OnBeginInteraction(const FInputActionValue& Value) +{ + const FVector InteractionLocation = GetAttachParent()->GetComponentLocation(); + + if (CurrentInteractableComponentsInRange.IsEmpty()) + return; + + if (bOnlyInteractWithClosestActor) + { + auto MinElement = *Algo::MinElementBy( + CurrentInteractableComponentsInRange, + [&](auto Element) + { return FVector(Element->GetOwner()->GetActorLocation() - InteractionLocation).Size(); }); + MinElement->HandleOnActionStartEvents(this, InteractionInputAction, Value, EInteractorType::Direct); + CurrentlyInteractedComponents = {MinElement}; + } + else + { + CurrentlyInteractedComponents.Reserve(CurrentlyInteractedComponents.Num() + + CurrentInteractableComponentsInRange.Num()); + for (UInteractableComponent* InteractableComp : CurrentInteractableComponentsInRange) + { + InteractableComp->HandleOnActionStartEvents(this, InteractionInputAction, Value, EInteractorType::Direct); + CurrentlyInteractedComponents.Add(InteractableComp); + } + } +} + +void UDirectInteractionComponent::OnEndInteraction(const FInputActionValue& Value) +{ + for (auto& Component : CurrentlyInteractedComponents) + { + if (Component.IsValid()) + { + Component->HandleOnActionEndEvents(this, InteractionInputAction, Value, EInteractorType::Direct); + } + } +} + +UInteractableComponent* UDirectInteractionComponent::SearchForInteractable(AActor* HitActor) +{ + UInteractableComponent* InteractableComponent = nullptr; + if (!HitActor) + { + UE_LOGFMT(Toolkit, Warning, + "UDirectInteractionComponent::SearchForInteractable: HitActor was nullptr, returning nullptr"); + return nullptr; + } + + if (HitActor->IsChildActor()) + { + // search for UInteractable upwards from hit geometry and return first one found + InteractableComponent = HitActor->FindComponentByClass<UInteractableComponent>(); + // if InteractableComponen is not valid search at parent + if (!InteractableComponent) + { + HitActor = HitActor->GetParentActor(); + if (HitActor) + { + bSearchAtParent = true; + return SearchForInteractable(HitActor); + } + } + } + else if (!HitActor->IsChildActor()) + { + InteractableComponent = HitActor->FindComponentByClass<UInteractableComponent>(); + } + + if (InteractableComponent) + { + // in the case, were we had to iterate up the hierarchy, check if we are allowed + // to interact with the parent via child geometry + if (bSearchAtParent && !InteractableComponent->bAllowInteractionFromChildGeometry) + { + InteractableComponent = nullptr; + } + } + bSearchAtParent = false; + return InteractableComponent; +} diff --git a/Source/RWTHVRToolkit/Private/Interaction/Interactors/GrabComponent.cpp b/Source/RWTHVRToolkit/Private/Interaction/Interactors/GrabComponent.cpp deleted file mode 100644 index 7429a615013b4fa35b77171cb82e58ff9e738075..0000000000000000000000000000000000000000 --- a/Source/RWTHVRToolkit/Private/Interaction/Interactors/GrabComponent.cpp +++ /dev/null @@ -1,178 +0,0 @@ -// Fill out your copyright notice in the Description page of Project Settings. - - -#include "Interaction/Interactors/GrabComponent.h" - -#include "EnhancedInputComponent.h" -#include "Interaction/Interactables/InteractableComponent.h" -#include "Interaction/Interactables/InteractionBitSet.h" - -#include "Kismet/GameplayStatics.h" -#include "Logging/StructuredLog.h" -#include "Utility/RWTHVRUtilities.h" - -// Sets default values for this component's properties -UGrabComponent::UGrabComponent() -{ - // Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these - // features off to improve performance if you don't need them. - PrimaryComponentTick.bCanEverTick = true; - // ... -} - -void UGrabComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) -{ - Super::TickComponent(DeltaTime, TickType, ThisTickFunction); - - TArray<UInteractableComponent*> CurrentGrabCompsInRange; - - TArray<FHitResult> OutHits; - const ETraceTypeQuery TraceType = UEngineTypes::ConvertToTraceType(ECollisionChannel::ECC_PhysicsBody); - - auto DebugTrace = bShowDebugTrace ? EDrawDebugTrace::ForOneFrame : EDrawDebugTrace::None; - - UKismetSystemLibrary::SphereTraceMulti(GetWorld(), GetAttachParent()->GetComponentLocation(), - GetAttachParent()->GetComponentLocation(), GrabSphereRadius, TraceType, true, - ActorsToIgnore, DebugTrace, OutHits, true, FColor::Green); - - for (FHitResult Hit : OutHits) - { - AActor* HitActor = Hit.GetActor(); - if (HitActor) - { - UInteractableComponent* Grabbable = SearchForInteractable(HitActor); - if (Grabbable && Grabbable->HasInteractionTypeFlag(EInteractorType::Grab) && Grabbable->IsInteractable) - { - Grabbable->HitResult = Hit; - CurrentGrabCompsInRange.AddUnique(Grabbable); - } - } - } - - CurrentGrabBehavioursInRange = CurrentGrabCompsInRange; - - // Call hover start events on all components that were not in range before - for (UInteractableComponent* CurrentGrabbable : CurrentGrabCompsInRange) - { - if (!PreviousGrabBehavioursInRange.Contains(CurrentGrabbable)) - { - PreviousGrabBehavioursInRange.AddUnique(CurrentGrabbable); - CurrentGrabbable->HandleOnHoverStartEvents(this, EInteractorType::Grab); - } - } - - TArray<UInteractableComponent*> ComponentsToRemove; - - // Call hover end events on all components that were previously in range, but not anymore - for (UInteractableComponent* PrevGrabbale : PreviousGrabBehavioursInRange) - { - if (!CurrentGrabCompsInRange.Contains(PrevGrabbale)) - { - ComponentsToRemove.AddUnique(PrevGrabbale); - PrevGrabbale->HandleOnHoverEndEvents(this, EInteractorType::Grab); - } - } - - for (UInteractableComponent* CompToRemove : ComponentsToRemove) - { - PreviousGrabBehavioursInRange.Remove(CompToRemove); - } -} - -void UGrabComponent::SetupPlayerInput(UInputComponent* PlayerInputComponent) -{ - IInputExtensionInterface::SetupPlayerInput(PlayerInputComponent); - - const APawn* Pawn = Cast<APawn>(GetOwner()); - if (!Pawn) - return; - - // Probably not the best place to add this. - ActorsToIgnore.AddUnique(GetOwner()); - - UEnhancedInputComponent* EI = Cast<UEnhancedInputComponent>(Pawn->InputComponent); - if (EI == nullptr) - return; - - EI->BindAction(GrabInputAction, ETriggerEvent::Started, this, &UGrabComponent::OnBeginGrab); - EI->BindAction(GrabInputAction, ETriggerEvent::Completed, this, &UGrabComponent::OnEndGrab); -} - -void UGrabComponent::OnBeginGrab(const FInputActionValue& Value) -{ - const FVector GrabLocation = GetAttachParent()->GetComponentLocation(); - - if (CurrentGrabBehavioursInRange.IsEmpty()) - return; - - if (bOnlyGrabClosestActor) - { - auto MinElement = *Algo::MinElementBy( - CurrentGrabBehavioursInRange, - [&](auto Element) { return FVector(Element->GetOwner()->GetActorLocation() - GrabLocation).Size(); }); - MinElement->HandleOnActionStartEvents(this, GrabInputAction, Value, EInteractorType::Grab); - CurrentlyGrabbedComponents = {MinElement}; - } - else - { - CurrentlyGrabbedComponents.Reserve(CurrentlyGrabbedComponents.Num() + CurrentGrabBehavioursInRange.Num()); - for (UInteractableComponent* Grabbable : CurrentGrabBehavioursInRange) - { - Grabbable->HandleOnActionStartEvents(this, GrabInputAction, Value, EInteractorType::Grab); - CurrentlyGrabbedComponents.Add(Grabbable); - } - } -} - -void UGrabComponent::OnEndGrab(const FInputActionValue& Value) -{ - for (auto& Component : CurrentlyGrabbedComponents) - { - if (Component.IsValid()) - { - Component->HandleOnActionEndEvents(this, GrabInputAction, Value, EInteractorType::Grab); - } - } -} - -UInteractableComponent* UGrabComponent::SearchForInteractable(AActor* HitActor) -{ - UInteractableComponent* Grabbable = nullptr; - if (!HitActor) - { - UE_LOGFMT(Toolkit, Warning, "UGrabComponent::SearchForInteractable: HitActor was nullptr, returning nullptr"); - return nullptr; - } - - if (HitActor->IsChildActor()) - { - // search for UInteractable upwards from hit geometry and return first one found - Grabbable = HitActor->FindComponentByClass<UInteractableComponent>(); - // if Grabbable is not valid search at parent - if (!Grabbable) - { - HitActor = HitActor->GetParentActor(); - if (HitActor) - { - bSearchAtParent = true; - return SearchForInteractable(HitActor); - } - } - } - else if (!HitActor->IsChildActor()) - { - Grabbable = HitActor->FindComponentByClass<UInteractableComponent>(); - } - - if (Grabbable) - { - // in the case, were we had to iterate up the hierarchy, check if we are allowed - // to grab the parent via child geometry - if (bSearchAtParent && !Grabbable->bAllowInteractionFromChildGeometry) - { - Grabbable = nullptr; - } - } - bSearchAtParent = false; - return Grabbable; -} diff --git a/Source/RWTHVRToolkit/Private/Interaction/Interactors/RWTHVRWidgetInteractionComponent.cpp b/Source/RWTHVRToolkit/Private/Interaction/Interactors/RWTHVRWidgetInteractionComponent.cpp index 020ae40bff8e17f164d2e7d895ae5860aab93de9..3a87de65d2cb52a5bce0dd0aa71af9dd3b2f69bb 100644 --- a/Source/RWTHVRToolkit/Private/Interaction/Interactors/RWTHVRWidgetInteractionComponent.cpp +++ b/Source/RWTHVRToolkit/Private/Interaction/Interactors/RWTHVRWidgetInteractionComponent.cpp @@ -4,7 +4,7 @@ #include "Interaction/Interactors/RWTHVRWidgetInteractionComponent.h" #include "EnhancedInputComponent.h" -#include "Interaction/Interactors/GrabComponent.h" +#include "Interaction/Interactors/DirectInteractionComponent.h" #include "Logging/StructuredLog.h" #include "Misc/Optional.h" #include "Utility/RWTHVRUtilities.h" diff --git a/Source/RWTHVRToolkit/Private/Interaction/Interactors/RaycastSelectionComponent.cpp b/Source/RWTHVRToolkit/Private/Interaction/Interactors/RaycastInteractionComponent.cpp similarity index 60% rename from Source/RWTHVRToolkit/Private/Interaction/Interactors/RaycastSelectionComponent.cpp rename to Source/RWTHVRToolkit/Private/Interaction/Interactors/RaycastInteractionComponent.cpp index e10a44b0053726512f1ed80e98e853e411675377..94afba4b4426fe1b861d787826f0e1cc11d6583b 100644 --- a/Source/RWTHVRToolkit/Private/Interaction/Interactors/RaycastSelectionComponent.cpp +++ b/Source/RWTHVRToolkit/Private/Interaction/Interactors/RaycastInteractionComponent.cpp @@ -1,14 +1,14 @@ // Fill out your copyright notice in the Description page of Project Settings. -#include "Interaction/Interactors/RaycastSelectionComponent.h" +#include "Interaction/Interactors/RaycastInteractionComponent.h" #include "EnhancedInputComponent.h" #include "Interaction/Interactables/InteractableComponent.h" #include "Kismet/KismetSystemLibrary.h" // Sets default values for this component's properties -URaycastSelectionComponent::URaycastSelectionComponent() +URaycastInteractionComponent::URaycastInteractionComponent() { // Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these // features off to improve performance if you don't need them. @@ -18,12 +18,12 @@ URaycastSelectionComponent::URaycastSelectionComponent() } // Called every frame -void URaycastSelectionComponent::TickComponent(float DeltaTime, ELevelTick TickType, - FActorComponentTickFunction* ThisTickFunction) +void URaycastInteractionComponent::TickComponent(float DeltaTime, ELevelTick TickType, + FActorComponentTickFunction* ThisTickFunction) { Super::TickComponent(DeltaTime, TickType, ThisTickFunction); - UInteractableComponent* CurrentSelectable = nullptr; + UInteractableComponent* NewInteractableComponent = nullptr; TArray<AActor*> ActorsToIgnore; @@ -40,15 +40,15 @@ void URaycastSelectionComponent::TickComponent(float DeltaTime, ELevelTick TickT AActor* HitActor = Hit.GetActor(); if (HitActor) { - UInteractableComponent* Selectable = HitActor->FindComponentByClass<UInteractableComponent>(); - if (Selectable && Selectable->IsInteractable) + UInteractableComponent* InteractableComponent = HitActor->FindComponentByClass<UInteractableComponent>(); + if (InteractableComponent && InteractableComponent->IsInteractable) { - CurrentSelectable = Selectable; - Selectable->HitResult = Hit; + NewInteractableComponent = InteractableComponent; + InteractableComponent->HitResult = Hit; } } - CurrentInteractable = CurrentSelectable; + CurrentInteractable = NewInteractableComponent; if (CurrentInteractable != PreviousInteractable) { @@ -61,19 +61,19 @@ void URaycastSelectionComponent::TickComponent(float DeltaTime, ELevelTick TickT PreviousInteractable = CurrentInteractable; } -void URaycastSelectionComponent::OnBeginSelect(const FInputActionValue& Value) +void URaycastInteractionComponent::OnBeginInteraction(const FInputActionValue& Value) { if (CurrentInteractable && CurrentInteractable->HasInteractionTypeFlag(EInteractorType::Raycast)) - CurrentInteractable->HandleOnActionStartEvents(this, RayCastSelectInputAction, Value, EInteractorType::Raycast); + CurrentInteractable->HandleOnActionStartEvents(this, InteractionInputAction, Value, EInteractorType::Raycast); } -void URaycastSelectionComponent::OnEndSelect(const FInputActionValue& Value) +void URaycastInteractionComponent::OnEndInteraction(const FInputActionValue& Value) { if (CurrentInteractable && CurrentInteractable->HasInteractionTypeFlag(EInteractorType::Raycast)) - CurrentInteractable->HandleOnActionEndEvents(this, RayCastSelectInputAction, Value, EInteractorType::Raycast); + CurrentInteractable->HandleOnActionEndEvents(this, InteractionInputAction, Value, EInteractorType::Raycast); } -void URaycastSelectionComponent::SetupPlayerInput(UInputComponent* PlayerInputComponent) +void URaycastInteractionComponent::SetupPlayerInput(UInputComponent* PlayerInputComponent) { IInputExtensionInterface::SetupPlayerInput(PlayerInputComponent); @@ -85,6 +85,8 @@ void URaycastSelectionComponent::SetupPlayerInput(UInputComponent* PlayerInputCo if (!EI) return; - EI->BindAction(RayCastSelectInputAction, ETriggerEvent::Started, this, &URaycastSelectionComponent::OnBeginSelect); - EI->BindAction(RayCastSelectInputAction, ETriggerEvent::Completed, this, &URaycastSelectionComponent::OnEndSelect); + EI->BindAction(InteractionInputAction, ETriggerEvent::Started, this, + &URaycastInteractionComponent::OnBeginInteraction); + EI->BindAction(InteractionInputAction, ETriggerEvent::Completed, this, + &URaycastInteractionComponent::OnEndInteraction); } diff --git a/Source/RWTHVRToolkit/Public/Interaction/Interactables/InteractionBitSet.h b/Source/RWTHVRToolkit/Public/Interaction/Interactables/InteractionBitSet.h index a317318d9d4af78e1a640c76ce6e7629dbbefae7..f2faaebab1f5288633cf68fba9773a4cd076c952 100644 --- a/Source/RWTHVRToolkit/Public/Interaction/Interactables/InteractionBitSet.h +++ b/Source/RWTHVRToolkit/Public/Interaction/Interactables/InteractionBitSet.h @@ -6,7 +6,7 @@ enum EInteractorType : int None = 0 UMETA(Hidden), Raycast = 1 << 0, Spherecast = 1 << 1, - Grab = 1 << 2, + Direct = 1 << 2, Reserved2 = 1 << 3, Reserved3 = 1 << 4, Reserved4 = 1 << 5, diff --git a/Source/RWTHVRToolkit/Public/Interaction/Interactors/DirectInteractionComponent.h b/Source/RWTHVRToolkit/Public/Interaction/Interactors/DirectInteractionComponent.h new file mode 100644 index 0000000000000000000000000000000000000000..69ef74ff844a727c11a333047a7f011a12d01241 --- /dev/null +++ b/Source/RWTHVRToolkit/Public/Interaction/Interactors/DirectInteractionComponent.h @@ -0,0 +1,58 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "Components/SceneComponent.h" +#include "Interaction/Interactables/InteractableComponent.h" +#include "Pawn/InputExtensionInterface.h" +#include "DirectInteractionComponent.generated.h" + +UCLASS(Abstract, Blueprintable) +class RWTHVRTOOLKIT_API UDirectInteractionComponent : public USceneComponent, public IInputExtensionInterface +{ + GENERATED_BODY() + +public: + // Sets default values for this component's properties + UDirectInteractionComponent(); + + virtual void TickComponent(float DeltaTime, ELevelTick TickType, + FActorComponentTickFunction* ThisTickFunction) override; + + UPROPERTY(EditAnywhere, Category = "Input") + class UInputAction* InteractionInputAction; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Direct Interaction") + float InteractionSphereRadius = 15.0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Direct Interaction") + bool bShowDebugTrace = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Direct Interaction") + bool bOnlyInteractWithClosestActor = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Direct Interaction") + TArray<AActor*> ActorsToIgnore; + + virtual void SetupPlayerInput(UInputComponent* PlayerInputComponent) override; + +private: + UFUNCTION() + void OnBeginInteraction(const FInputActionValue& Value); + + UFUNCTION() + void OnEndInteraction(const FInputActionValue& Value); + + UPROPERTY() + TArray<UInteractableComponent*> PreviousInteractableComponentsInRange; + + UPROPERTY() + TArray<UInteractableComponent*> CurrentInteractableComponentsInRange; + + TArray<TWeakObjectPtr<UInteractableComponent>> CurrentlyInteractedComponents; + + UInteractableComponent* SearchForInteractable(AActor* HitActor); + + bool bSearchAtParent = false; +}; diff --git a/Source/RWTHVRToolkit/Public/Interaction/Interactors/GrabComponent.h b/Source/RWTHVRToolkit/Public/Interaction/Interactors/GrabComponent.h deleted file mode 100644 index 4e18d911a41ad79fbcb4cf4d6d1e914d11f74b5f..0000000000000000000000000000000000000000 --- a/Source/RWTHVRToolkit/Public/Interaction/Interactors/GrabComponent.h +++ /dev/null @@ -1,60 +0,0 @@ -// Fill out your copyright notice in the Description page of Project Settings. - -#pragma once - -#include "CoreMinimal.h" -#include "Components/SceneComponent.h" -#include "Interaction/Interactables/InteractableComponent.h" -#include "Pawn/InputExtensionInterface.h" -#include "GrabComponent.generated.h" - -class UGrabbableComponent; - -UCLASS(Abstract, Blueprintable) -class RWTHVRTOOLKIT_API UGrabComponent : public USceneComponent, public IInputExtensionInterface -{ - GENERATED_BODY() - -public: - // Sets default values for this component's properties - UGrabComponent(); - - virtual void TickComponent(float DeltaTime, ELevelTick TickType, - FActorComponentTickFunction* ThisTickFunction) override; - - UPROPERTY(EditAnywhere, Category = "Input") - class UInputAction* GrabInputAction; - - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Grabbing") - float GrabSphereRadius = 15.0; - - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Grabbing") - bool bShowDebugTrace = false; - - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Grabbing") - bool bOnlyGrabClosestActor = false; - - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Grabbing") - TArray<AActor*> ActorsToIgnore; - - virtual void SetupPlayerInput(UInputComponent* PlayerInputComponent) override; - -private: - UFUNCTION() - void OnBeginGrab(const FInputActionValue& Value); - - UFUNCTION() - void OnEndGrab(const FInputActionValue& Value); - - UPROPERTY() - TArray<UInteractableComponent*> PreviousGrabBehavioursInRange; - - UPROPERTY() - TArray<UInteractableComponent*> CurrentGrabBehavioursInRange; - - TArray<TWeakObjectPtr<UInteractableComponent>> CurrentlyGrabbedComponents; - - UInteractableComponent* SearchForInteractable(AActor* HitActor); - - bool bSearchAtParent = false; -}; diff --git a/Source/RWTHVRToolkit/Public/Interaction/Interactors/RaycastSelectionComponent.h b/Source/RWTHVRToolkit/Public/Interaction/Interactors/RaycastInteractionComponent.h similarity index 73% rename from Source/RWTHVRToolkit/Public/Interaction/Interactors/RaycastSelectionComponent.h rename to Source/RWTHVRToolkit/Public/Interaction/Interactors/RaycastInteractionComponent.h index b77f9ca80f6b66bdce3d47771bfab14d9daa39b8..7d9422c24c8df31cfb8b94008445a683113bc930 100644 --- a/Source/RWTHVRToolkit/Public/Interaction/Interactors/RaycastSelectionComponent.h +++ b/Source/RWTHVRToolkit/Public/Interaction/Interactors/RaycastInteractionComponent.h @@ -6,24 +6,24 @@ #include "CoreMinimal.h" #include "Components/SceneComponent.h" -#include "RaycastSelectionComponent.generated.h" +#include "RaycastInteractionComponent.generated.h" UCLASS(Abstract, Blueprintable) -class RWTHVRTOOLKIT_API URaycastSelectionComponent : public USceneComponent, public IInputExtensionInterface +class RWTHVRTOOLKIT_API URaycastInteractionComponent : public USceneComponent, public IInputExtensionInterface { GENERATED_BODY() public: // Sets default values for this component's properties - URaycastSelectionComponent(); + URaycastInteractionComponent(); // Called every frame virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; UPROPERTY(EditAnywhere, Category = "Input") - class UInputAction* RayCastSelectInputAction; + class UInputAction* InteractionInputAction; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Raycast") float TraceLength = 3000.0; @@ -32,10 +32,10 @@ public: private: UFUNCTION() - void OnBeginSelect(const FInputActionValue& Value); + void OnBeginInteraction(const FInputActionValue& Value); UFUNCTION() - void OnEndSelect(const FInputActionValue& Value); + void OnEndInteraction(const FInputActionValue& Value); public: virtual void SetupPlayerInput(UInputComponent* PlayerInputComponent) override;