Skip to content
Snippets Groups Projects
Commit 8881f577 authored by David Gilbert's avatar David Gilbert :bug:
Browse files

Merge branch 'refactor/rename_interactions' into 'dev/5.3'

Interaction Naming Adjustments and Consistency changes

See merge request !72
parents f0eed075 5ff2e363
Branches
Tags
2 merge requests!80UE5.3-2023.1-rc2,!72Interaction Naming Adjustments and Consistency changes
Pipeline #355755 passed
Showing
with 285 additions and 26 deletions
......@@ -5,3 +5,17 @@
+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")
+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
File added
File added
File deleted
File deleted
File deleted
File deleted
File added
File added
No preview for this file type
No preview for this file type
// Fill out your copyright notice in the Description page of Project Settings.
#include "Interaction/Interactors/GrabComponent.h"
#include "Interaction/Interactors/DirectInteractionComponent.h"
#include "EnhancedInputComponent.h"
#include "Interaction/Interactables/InteractableComponent.h"
......@@ -12,7 +12,7 @@
#include "Utility/RWTHVRUtilities.h"
// Sets default values for this component's properties
UGrabComponent::UGrabComponent()
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.
......@@ -20,11 +20,12 @@ UGrabComponent::UGrabComponent()
// ...
}
void UGrabComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
void UDirectInteractionComponent::TickComponent(float DeltaTime, ELevelTick TickType,
FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
TArray<UInteractableComponent*> CurrentGrabCompsInRange;
TArray<UInteractableComponent*> CurrentInteractableCompsInRange;
TArray<FHitResult> OutHits;
const ETraceTypeQuery TraceType = UEngineTypes::ConvertToTraceType(ECollisionChannel::ECC_PhysicsBody);
......@@ -32,54 +33,55 @@ void UGrabComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorC
auto DebugTrace = bShowDebugTrace ? EDrawDebugTrace::ForOneFrame : EDrawDebugTrace::None;
UKismetSystemLibrary::SphereTraceMulti(GetWorld(), GetAttachParent()->GetComponentLocation(),
GetAttachParent()->GetComponentLocation(), GrabSphereRadius, TraceType, true,
ActorsToIgnore, DebugTrace, OutHits, true, FColor::Green);
GetAttachParent()->GetComponentLocation(), InteractionSphereRadius,
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)
UInteractableComponent* InteractableComp = SearchForInteractable(HitActor);
if (InteractableComp && InteractableComp->HasInteractionTypeFlag(EInteractorType::Direct) &&
InteractableComp->IsInteractable)
{
Grabbable->HitResult = Hit;
CurrentGrabCompsInRange.AddUnique(Grabbable);
InteractableComp->HitResult = Hit;
CurrentInteractableCompsInRange.AddUnique(InteractableComp);
}
}
}
CurrentGrabBehavioursInRange = CurrentGrabCompsInRange;
CurrentInteractableComponentsInRange = CurrentInteractableCompsInRange;
// Call hover start events on all components that were not in range before
for (UInteractableComponent* CurrentGrabbable : CurrentGrabCompsInRange)
for (UInteractableComponent* CurrentInteractableComp : CurrentInteractableCompsInRange)
{
if (!PreviousGrabBehavioursInRange.Contains(CurrentGrabbable))
if (!PreviousInteractableComponentsInRange.Contains(CurrentInteractableComp))
{
PreviousGrabBehavioursInRange.AddUnique(CurrentGrabbable);
CurrentGrabbable->HandleOnHoverStartEvents(this, EInteractorType::Grab);
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* PrevGrabbale : PreviousGrabBehavioursInRange)
for (UInteractableComponent* PrevInteractableComp : PreviousInteractableComponentsInRange)
{
if (!CurrentGrabCompsInRange.Contains(PrevGrabbale))
if (!CurrentInteractableCompsInRange.Contains(PrevInteractableComp))
{
ComponentsToRemove.AddUnique(PrevGrabbale);
PrevGrabbale->HandleOnHoverEndEvents(this, EInteractorType::Grab);
ComponentsToRemove.AddUnique(PrevInteractableComp);
PrevInteractableComp->HandleOnHoverEndEvents(this, EInteractorType::Direct);
}
}
for (UInteractableComponent* CompToRemove : ComponentsToRemove)
{
PreviousGrabBehavioursInRange.Remove(CompToRemove);
PreviousInteractableComponentsInRange.Remove(CompToRemove);
}
}
void UGrabComponent::SetupPlayerInput(UInputComponent* PlayerInputComponent)
void UDirectInteractionComponent::SetupPlayerInput(UInputComponent* PlayerInputComponent)
{
IInputExtensionInterface::SetupPlayerInput(PlayerInputComponent);
......@@ -94,62 +96,67 @@ void UGrabComponent::SetupPlayerInput(UInputComponent* PlayerInputComponent)
if (EI == nullptr)
return;
EI->BindAction(GrabInputAction, ETriggerEvent::Started, this, &UGrabComponent::OnBeginGrab);
EI->BindAction(GrabInputAction, ETriggerEvent::Completed, this, &UGrabComponent::OnEndGrab);
EI->BindAction(InteractionInputAction, ETriggerEvent::Started, this,
&UDirectInteractionComponent::OnBeginInteraction);
EI->BindAction(InteractionInputAction, ETriggerEvent::Completed, this,
&UDirectInteractionComponent::OnEndInteraction);
}
void UGrabComponent::OnBeginGrab(const FInputActionValue& Value)
void UDirectInteractionComponent::OnBeginInteraction(const FInputActionValue& Value)
{
const FVector GrabLocation = GetAttachParent()->GetComponentLocation();
const FVector InteractionLocation = GetAttachParent()->GetComponentLocation();
if (CurrentGrabBehavioursInRange.IsEmpty())
if (CurrentInteractableComponentsInRange.IsEmpty())
return;
if (bOnlyGrabClosestActor)
if (bOnlyInteractWithClosestActor)
{
auto MinElement = *Algo::MinElementBy(
CurrentGrabBehavioursInRange,
[&](auto Element) { return FVector(Element->GetOwner()->GetActorLocation() - GrabLocation).Size(); });
MinElement->HandleOnActionStartEvents(this, GrabInputAction, Value, EInteractorType::Grab);
CurrentlyGrabbedComponents = {MinElement};
CurrentInteractableComponentsInRange,
[&](auto Element)
{ return FVector(Element->GetOwner()->GetActorLocation() - InteractionLocation).Size(); });
MinElement->HandleOnActionStartEvents(this, InteractionInputAction, Value, EInteractorType::Direct);
CurrentlyInteractedComponents = {MinElement};
}
else
{
CurrentlyGrabbedComponents.Reserve(CurrentlyGrabbedComponents.Num() + CurrentGrabBehavioursInRange.Num());
for (UInteractableComponent* Grabbable : CurrentGrabBehavioursInRange)
CurrentlyInteractedComponents.Reserve(CurrentlyInteractedComponents.Num() +
CurrentInteractableComponentsInRange.Num());
for (UInteractableComponent* InteractableComp : CurrentInteractableComponentsInRange)
{
Grabbable->HandleOnActionStartEvents(this, GrabInputAction, Value, EInteractorType::Grab);
CurrentlyGrabbedComponents.Add(Grabbable);
InteractableComp->HandleOnActionStartEvents(this, InteractionInputAction, Value, EInteractorType::Direct);
CurrentlyInteractedComponents.Add(InteractableComp);
}
}
}
void UGrabComponent::OnEndGrab(const FInputActionValue& Value)
void UDirectInteractionComponent::OnEndInteraction(const FInputActionValue& Value)
{
for (auto& Component : CurrentlyGrabbedComponents)
for (auto& Component : CurrentlyInteractedComponents)
{
if (Component.IsValid())
{
Component->HandleOnActionEndEvents(this, GrabInputAction, Value, EInteractorType::Grab);
Component->HandleOnActionEndEvents(this, InteractionInputAction, Value, EInteractorType::Direct);
}
}
}
UInteractableComponent* UGrabComponent::SearchForInteractable(AActor* HitActor)
UInteractableComponent* UDirectInteractionComponent::SearchForInteractable(AActor* HitActor)
{
UInteractableComponent* Grabbable = nullptr;
UInteractableComponent* InteractableComponent = nullptr;
if (!HitActor)
{
UE_LOGFMT(Toolkit, Warning, "UGrabComponent::SearchForInteractable: HitActor was nullptr, returning nullptr");
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
Grabbable = HitActor->FindComponentByClass<UInteractableComponent>();
// if Grabbable is not valid search at parent
if (!Grabbable)
InteractableComponent = HitActor->FindComponentByClass<UInteractableComponent>();
// if InteractableComponen is not valid search at parent
if (!InteractableComponent)
{
HitActor = HitActor->GetParentActor();
if (HitActor)
......@@ -161,18 +168,18 @@ UInteractableComponent* UGrabComponent::SearchForInteractable(AActor* HitActor)
}
else if (!HitActor->IsChildActor())
{
Grabbable = HitActor->FindComponentByClass<UInteractableComponent>();
InteractableComponent = HitActor->FindComponentByClass<UInteractableComponent>();
}
if (Grabbable)
if (InteractableComponent)
{
// 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)
// to interact with the parent via child geometry
if (bSearchAtParent && !InteractableComponent->bAllowInteractionFromChildGeometry)
{
Grabbable = nullptr;
InteractableComponent = nullptr;
}
}
bSearchAtParent = false;
return Grabbable;
return InteractableComponent;
}
......@@ -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"
......
// 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,
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);
}
......@@ -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,
......
......@@ -6,53 +6,51 @@
#include "Components/SceneComponent.h"
#include "Interaction/Interactables/InteractableComponent.h"
#include "Pawn/InputExtensionInterface.h"
#include "GrabComponent.generated.h"
class UGrabbableComponent;
#include "DirectInteractionComponent.generated.h"
UCLASS(Abstract, Blueprintable)
class RWTHVRTOOLKIT_API UGrabComponent : public USceneComponent, public IInputExtensionInterface
class RWTHVRTOOLKIT_API UDirectInteractionComponent : public USceneComponent, public IInputExtensionInterface
{
GENERATED_BODY()
public:
// Sets default values for this component's properties
UGrabComponent();
UDirectInteractionComponent();
virtual void TickComponent(float DeltaTime, ELevelTick TickType,
FActorComponentTickFunction* ThisTickFunction) override;
UPROPERTY(EditAnywhere, Category = "Input")
class UInputAction* GrabInputAction;
class UInputAction* InteractionInputAction;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Grabbing")
float GrabSphereRadius = 15.0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Direct Interaction")
float InteractionSphereRadius = 15.0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Grabbing")
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Direct Interaction")
bool bShowDebugTrace = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Grabbing")
bool bOnlyGrabClosestActor = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Direct Interaction")
bool bOnlyInteractWithClosestActor = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Grabbing")
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Direct Interaction")
TArray<AActor*> ActorsToIgnore;
virtual void SetupPlayerInput(UInputComponent* PlayerInputComponent) override;
private:
UFUNCTION()
void OnBeginGrab(const FInputActionValue& Value);
void OnBeginInteraction(const FInputActionValue& Value);
UFUNCTION()
void OnEndGrab(const FInputActionValue& Value);
void OnEndInteraction(const FInputActionValue& Value);
UPROPERTY()
TArray<UInteractableComponent*> PreviousGrabBehavioursInRange;
TArray<UInteractableComponent*> PreviousInteractableComponentsInRange;
UPROPERTY()
TArray<UInteractableComponent*> CurrentGrabBehavioursInRange;
TArray<UInteractableComponent*> CurrentInteractableComponentsInRange;
TArray<TWeakObjectPtr<UInteractableComponent>> CurrentlyGrabbedComponents;
TArray<TWeakObjectPtr<UInteractableComponent>> CurrentlyInteractedComponents;
UInteractableComponent* SearchForInteractable(AActor* HitActor);
......
......@@ -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;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment