Skip to content
Snippets Groups Projects
Commit 6d4fb12d authored by Daniel Rupp's avatar Daniel Rupp
Browse files

feat(navigation): adds new teleport visualizer bp and base class, reworks...

feat(navigation): adds new teleport visualizer bp and base class, reworks teleport component to handle height teleportation.
parent eb40e87e
No related branches found
No related tags found
No related merge requests found
Pipeline #407968 failed
Showing
with 563 additions and 28 deletions
File added
No preview for this file type
File added
File added
No preview for this file type
No preview for this file type
......@@ -12,7 +12,8 @@
#include "NiagaraDataInterfaceArrayFunctionLibrary.h"
#include "Utility/RWTHVRUtilities.h"
#include "MotionControllerComponent.h"
#include "Camera/CameraComponent.h"
#include "Kismet/KismetMathLibrary.h"
void UTeleportationComponent::SetupPlayerInput(UInputComponent* PlayerInputComponent)
{
......@@ -35,10 +36,14 @@ void UTeleportationComponent::SetupPlayerInput(UInputComponent* PlayerInputCompo
}
TeleportVisualizer =
GetWorld()->SpawnActor<AActor>(BPTeleportVisualizer, VRPawn->GetActorLocation(), VRPawn->GetActorRotation());
GetWorld()->SpawnActor<ATeleportVisualizer>(BPTeleportVisualizer, VRPawn->GetActorLocation(), VRPawn->GetActorRotation());
TeleportTraceComponent->SetVisibility(false);
TeleportVisualizer->SetActorHiddenInGame(true);
TeleportVisualizer->Platform->SetHiddenInGame(false);
FVector PawnBottomLocation = VRPawn->GetActorLocation();
PawnBottomLocation.Z = VRPawn->GetActorLocation().Z;
TeleportVisualizer->Platform->SetWorldLocation(PawnBottomLocation);
// simple way of changing the handedness
if (bMoveWithRightHand)
......@@ -60,14 +65,60 @@ void UTeleportationComponent::SetupPlayerInput(UInputComponent* PlayerInputCompo
}
// teleporting
EI->BindAction(Move, ETriggerEvent::Started, this, &UTeleportationComponent::OnStartTeleportTrace);
EI->BindAction(Move, ETriggerEvent::Triggered, this, &UTeleportationComponent::UpdateTeleportTrace);
EI->BindAction(Move, ETriggerEvent::Completed, this, &UTeleportationComponent::OnEndTeleportTrace);
EI->BindAction(Move, ETriggerEvent::Canceled, this, &UTeleportationComponent::OnEndTeleportTrace);
EI->BindAction(Teleport, ETriggerEvent::Started, this, &UTeleportationComponent::OnStartTeleportTrace);
EI->BindAction(Teleport, ETriggerEvent::Triggered, this, &UTeleportationComponent::UpdateTeleportTrace);
EI->BindAction(Teleport, ETriggerEvent::Completed, this, &UTeleportationComponent::OnEndTeleportTrace);
EI->BindAction(Teleport, ETriggerEvent::Canceled, this, &UTeleportationComponent::OnEndTeleportTrace);
EI->BindAction(CancelTeleport,ETriggerEvent::Started, this, &UTeleportationComponent::OnCancelTeleport);
// turning is defined in MovementComponentBase
}
void UTeleportationComponent::PlayHapticEffect(UHapticFeedbackEffect_Base* HapticEffect, float Intensity)
{
Intensity = FMath::Clamp(Intensity, 0.f, 1.f);
APlayerController* PlayerController = UGameplayStatics::GetPlayerController(GetWorld(), 0);
PlayerController->PlayHapticEffect(HapticEffect, EControllerHand::Right,Intensity);
}
void UTeleportationComponent::CleanupTeleportVisualization()
{
if (!VRPawn)
return;
// End Teleport Trace
bTeleportTraceActive = false;
TeleportTraceComponent->SetVisibility(false);
TeleportVisualizer->SetActorHiddenInGame(true);
TeleportVisualizer->HorizontalIndicator->SetHiddenInGame(true);
TeleportVisualizer->VerticalIndicator->SetHiddenInGame(true);
//TeleportVisualizer->PreTravelPlatform->SetWorldLocation(TeleportVisualizer->Platform->GetComponentLocation());
bHasVerticalPhaseStarted=false;
bValidTeleportLocation = false;
}
void UTeleportationComponent::UpdateUserPreview()
{
FVector NewHMDPos = TeleportVisualizer->GetActorLocation();
NewHMDPos.Z += VRPawn->HeadCameraComponent->GetComponentLocation().Z - TeleportVisualizer->Platform->GetComponentLocation().Z; // works since the user stands on the platform (or at least on the same Z level)
TeleportVisualizer->HMDPreview->SetWorldLocationAndRotation(NewHMDPos, VRPawn->HeadCameraComponent->GetComponentRotation());
// set rotation of bodypreview
TeleportVisualizer->BodyPreview->SetWorldRotation(FRotator(0.0,-90,0));
FVector NewBodyPreviewPos = TeleportVisualizer->HMDPreview->GetComponentLocation();
NewBodyPreviewPos -= FVector(0, 0, TeleportVisualizer->HeadBodyDistance);
TeleportVisualizer->BodyPreview->SetWorldLocation(NewBodyPreviewPos);
// Set rotation of vertical indicator arrows to always face pawn
FRotator RotationToPawn = UKismetMathLibrary::FindLookAtRotation(TeleportVisualizer->VerticalIndicator->GetComponentLocation(), VRPawn->GetActorLocation());
// only rotate around Z axis
RotationToPawn.Pitch = 0;
RotationToPawn.Roll = 0;
TeleportVisualizer->VerticalIndicator->SetRelativeRotation(RotationToPawn);
}
// On button press -> show teleport trace
void UTeleportationComponent::OnStartTeleportTrace(const FInputActionValue& Value)
{
......@@ -75,12 +126,23 @@ void UTeleportationComponent::OnStartTeleportTrace(const FInputActionValue& Valu
bTeleportTraceActive = true;
TeleportTraceComponent->SetVisibility(true);
TeleportVisualizer->SetActorHiddenInGame(false);
// Reset cancel teleport functionality
bTeleportCancelled = false;
}
// called while button is pressed (Triggered)
void UTeleportationComponent::UpdateTeleportTrace(const FInputActionValue& Value)
void UTeleportationComponent::OnCancelTeleport(const FInputActionValue& Value)
{
CleanupTeleportVisualization();
bTeleportCancelled = true;
}
void UTeleportationComponent::SetPreTravelInformationVisibility(bool bVisibility)
{
}
void UTeleportationComponent::SelectHorizontalLocation()
{
// Update the teleport trace
const FVector StartPosition = TeleportationHand->GetComponentLocation();
const FVector ForwardVector = TeleportationHand->GetForwardVector();
......@@ -103,7 +165,7 @@ void UTeleportationComponent::UpdateTeleportTrace(const FInputActionValue& Value
if (bUseNavMesh)
{
FinalTeleportLocation = OutLocation;
SelectedHorizontalPosition = OutLocation;
if (bValidTeleportLocation != bValidProjection)
{
bValidTeleportLocation = bValidProjection;
......@@ -114,10 +176,13 @@ void UTeleportationComponent::UpdateTeleportTrace(const FInputActionValue& Value
{
if (bValidHit)
{
FinalTeleportLocation = HitLocation;
TeleportVisualizer->SetActorHiddenInGame(false);
// update location
TeleportVisualizer->SetActorLocation(FinalTeleportLocation);
SelectedHorizontalPosition = HitLocation;
// Don't sweep on first call to correctly initialize platform position
if(bIsFirstHorizontalCall)
{
TeleportVisualizer->PreTravelPlatform->SetWorldLocation(SelectedHorizontalPosition, false); // teleport pre travel mesh to impact point
bIsFirstHorizontalCall = false;
}
}
}
......@@ -131,6 +196,156 @@ void UTeleportationComponent::UpdateTeleportTrace(const FInputActionValue& Value
PathPoints);
}
void UTeleportationComponent::SelectVerticalLocation()
{
float OpeningAngle = GetAngleBetweenVectors(ReferenceVector, VRPawn->RightHand->GetForwardVector());
// don't change height if angle is below deadzone and the deadzone has never been left
if(abs(OpeningAngle) <= Deadzone && !hasLeftDeadZone)
{
//SetVerticalActorColor(FLinearColor::Gray);
PlayHapticEffect(TeleportVisualizer->HapticFeedback,0.1);
return;
}
//SetVerticalActorColor(FLinearColor::Blue); // indicate that vertical selection is now active only if the deadzone has been left
// if this is the first time the deadzone is left, play faint haptic cue to indicate that
if (hasLeftDeadZone == false)
{
PlayHapticEffect(TeleportVisualizer->HapticFeedback, 0.1); //
hasLeftDeadZone = true;// disable deadzone check if height change has begun
}
//UE_LOG(LogTemp, Warning, TEXT("OpeningAngle = %f"), OpeningAngle);
FVector NewPos = SelectedHorizontalPosition;
// "1:1" Movement if angle is below velocity zone
if (abs(OpeningAngle) < VelocityZone)
{
float FixedOffset = OpeningAngle * ElevationSpeed;
AngularOffset = OpeningAngle * ElevationSpeed;
NewPos.Z = NewPos.Z + AngularOffset + HeightOffset; // make movements correspond directly to controller angle
//NewPos.Z += HeightOffset; // account for height changes made in the velocity zone
TeleportVisualizer->PreTravelPlatform->SetWorldLocation(NewPos, true);
}
else // velocity-based movements if angle is within velocity zone
{
float Sign = (OpeningAngle < 0) ? -1 : 1; // determine the sign based on the opening angle
float OvershootAngle = (abs(OpeningAngle) - VelocityZone) * Sign; // determines how far we are above/below the velocity zone
/*float OldHeightOffset = HeightOffset;*/
HeightOffset += OvershootAngle * VelocitySpeed;
NewPos.Z += HeightOffset + AngularOffset;
/*bool bWasMoved =*/ TeleportVisualizer->PreTravelPlatform->SetWorldLocation(NewPos, true); // change location and check whether movement occurred or if platform was hitting ground
/*if(!bWasMoved)
{
HeightOffset = OldHeightOffset; //don't change height offset if the platform wasn't moved
}*/
}
}
float UTeleportationComponent::GetAngleBetweenVectors(FVector Vector1, FVector Vector2)
{
AngleProjectionPlane = FPlane(VRPawn->RightHand->GetComponentLocation(), VRPawn->RightHand->GetComponentLocation() + ReferenceVector, VRPawn->RightHand->GetComponentLocation() + FVector(0, 0, 1));
FVector MCLoc = VRPawn->RightHand->GetComponentLocation();
Vector1 = Vector1.GetSafeNormal();
Vector2 = Vector2.GetSafeNormal();
// Mapping the vectors to a plane somehow helps with jittery behaviour ?!
Vector1 = FVector::VectorPlaneProject(Vector1, AngleProjectionPlane.GetNormal());
Vector2 = FVector::VectorPlaneProject(Vector2, AngleProjectionPlane.GetNormal());
// Uncomment this to see the projection
//DrawDebugSolidPlane(GetWorld(), AngleProjectionPlane, RightMC->GetComponentLocation(), 50, FColor::Magenta, false, 1);
//DrawDebugDirectionalArrow(GetWorld(), MCLoc, MCLoc + Vector1 * 30, 5, FColor::Red, false, -1,1,2);
//DrawDebugDirectionalArrow(GetWorld(), MCLoc, MCLoc + Vector2 * 30, 5, FColor::Green, false, -1,1,2);
FVector CrossProduct = FVector::CrossProduct(Vector1,Vector2);
//DrawDebugDirectionalArrow(GetWorld(), MCLoc, MCLoc + PlaneNormal * 30, 5, FColor::Cyan, false, -1, 1, 2);
float OpeningAngle = FMath::Atan2(FVector::CrossProduct(Vector1, Vector2).Size(), FVector::DotProduct(Vector1, Vector2));
OpeningAngle = FMath::RadiansToDegrees(OpeningAngle);
// Take sign of cross product to determine if angle was opened upwards or downwards
float Distance = AngleProjectionPlane.PlaneDot(MCLoc + CrossProduct * 30);
return FMath::Sign(Distance) * OpeningAngle;
}
// called while button is pressed (Triggered)
void UTeleportationComponent::UpdateTeleportTrace(const FInputActionValue& Value)
{
float AxisValue = Value.Get<float>();
// If we have cancelled the teleport trace via a button press, return.
// Only allow teleportation again if teleport button is fully let down and pressed again
if(bTeleportCancelled)
{
return;
}
UpdateUserPreview();
if(TeleportState == ETeleportState::BaseState)
{
SetPreTravelInformationVisibility(true);
}
if(TeleportState != ETeleportState::VerticalSelection)
{
if(AxisValue <= TwoStepThreshold)
{
TeleportState = ETeleportState::HorizontalSelection;
}
if(AxisValue > TwoStepThreshold && bHorizontalPhaseCompleted)
{
if(!bHasVerticalPhaseStarted)
{
PlayHapticEffect(TeleportVisualizer->HapticFeedback,1);
bHasVerticalPhaseStarted = true;
}
TeleportState = ETeleportState::VerticalSelection;
// store current forward vector of right hand for further computations in the height selection phase
ReferenceVector = VRPawn->RightHand->GetForwardVector();
}
}
switch (TeleportState)
{
case ETeleportState::BaseState:
SetPreTravelInformationVisibility(true);
TeleportState = ETeleportState::HorizontalSelection;
break;
case ETeleportState::HorizontalSelection:
TeleportVisualizer->HorizontalIndicator->SetHiddenInGame(false);
SelectHorizontalLocation();
bHorizontalPhaseCompleted = true;
break;
case ETeleportState::VerticalSelection:
// Update the teleport trace
TeleportVisualizer->HorizontalIndicator->SetHiddenInGame(true);
TeleportVisualizer->VerticalIndicator->SetHiddenInGame(false);
SelectVerticalLocation();
break;
default:
UE_LOG(LogTemp,Error,TEXT("TeleportationComponent: Invalid Teleport Phase"))
break;
}
}
bool UTeleportationComponent::IsValidTeleportLocation(const FHitResult& Hit, FVector& ProjectedLocation) const
{
UNavigationSystemV1* NavSys = FNavigationSystem::GetCurrent<UNavigationSystemV1>(GetWorld());
......@@ -146,13 +361,18 @@ bool UTeleportationComponent::IsValidTeleportLocation(const FHitResult& Hit, FVe
// On button release -> remove trace and teleport user to location
void UTeleportationComponent::OnEndTeleportTrace(const FInputActionValue& Value)
{
if (!VRPawn)
return;
// End Teleport Trace
bTeleportTraceActive = false;
TeleportTraceComponent->SetVisibility(false);
TeleportVisualizer->SetActorHiddenInGame(true);
TeleportState=ETeleportState::BaseState;
HeightOffset=0; //reset height offset for next teleport
hasLeftDeadZone=false;
bIsFirstHorizontalCall=true;
bHorizontalPhaseCompleted=false;
bValidTeleportLocation = false;
VRPawn->TeleportTo(FinalTeleportLocation, VRPawn->GetActorRotation());
// If teleport was cancelled via button press, do not teleport.
// Allow teleportation again, if we let go and press the teleport button again.
if(bTeleportCancelled)
{
return;
}
CleanupTeleportVisualization();
VRPawn->TeleportTo(TeleportVisualizer->PreTravelPlatform->GetComponentLocation(), VRPawn->GetActorRotation());
}
// Fill out your copyright notice in the Description page of Project Settings.
#include "UI/TeleportVisualizer.h"
#include "MovieSceneSequenceID.h"
#include "NiagaraComponent.h"
#include "Engine/StaticMeshActor.h"
// Sets default values
ATeleportVisualizer::ATeleportVisualizer()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
RootComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Root"));
Platform = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("PlatformMesh"));
//Platform->SetStaticMesh(PlatformMesh);
// disable collisions of platform meshes
FCollisionResponseContainer ResponseContainerPlatform;
ResponseContainerPlatform.SetAllChannels(ECollisionResponse::ECR_Ignore);
PreTravelPlatform = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("PreTravelPlatformMesh"));
PreTravelPlatform->SetCollisionResponseToChannels(ResponseContainerPlatform); // Ignore collisions on all channels ..
PreTravelPlatform->SetCollisionResponseToChannel(ECollisionChannel::ECC_WorldStatic, ECollisionResponse::ECR_Block); // .. except WorldStatic channel
PreTravelPlatform->SetMobility(EComponentMobility::Movable);
// ### HMD Preview ###
// Create a static mesh component for the HMD preview
HMDPreview = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("HMD_PreviewMesh"));
HMDPreview->SetupAttachment(PreTravelPlatform);
//make HMD mesh slightly bigger for better visibility
FVector Scale = HMDPreview->GetRelativeScale3D();
Scale *= 1.2f;
HMDPreview->SetRelativeScale3D(Scale);
HMDPreview->SetCollisionEnabled(ECollisionEnabled::NoCollision); // disable collision
// Create body preview mesh which visualizes the approximate position of the users body
BodyPreview = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("BodyPreviewMesh"));
BodyPreview->SetupAttachment(HMDPreview);
BodyPreview->SetCollisionEnabled(ECollisionEnabled::NoCollision); // disable collision
// ### Ground Plane ###
// Create a static mesh component for the HMD preview
GroundPlane = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("GroundPlaneMesh"));
FCollisionResponseContainer ResponseContainerGroundPlane;
ResponseContainerGroundPlane.SetAllChannels(ECollisionResponse::ECR_Ignore);
GroundPlane->SetCollisionResponseToChannels(ResponseContainerGroundPlane); // Ignore collisions on all channels ..
GroundPlane->SetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn, ECollisionResponse::ECR_Block); // .. except pawn channel
GroundVisualizationNiagaraComponent = CreateDefaultSubobject<UNiagaraComponent>(TEXT("GroundParticleSystem"));
GroundVisualizationNiagaraComponent->SetupAttachment(RootComponent); // Attach it to the root component or any other desired parent component
// setup visuals (migrated from CreateTwoStepHandler function)
HorizontalIndicator = CreateDefaultSubobject<UChildActorComponent>("HorizontalIndicator");
VerticalIndicator = CreateDefaultSubobject<UChildActorComponent>("VerticalIndicator");
DefaultHorizontalRange = 4000;
}
// Called when the game starts or when spawned
void ATeleportVisualizer::BeginPlay()
{
Super::BeginPlay();
FActorSpawnParameters SpawnParameters;
HMDPreview->AttachToComponent(PreTravelPlatform,FAttachmentTransformRules(
EAttachmentRule::KeepRelative,
EAttachmentRule::KeepWorld,
EAttachmentRule::KeepRelative, false));
BodyPreview->AttachToComponent(HMDPreview, FAttachmentTransformRules(
EAttachmentRule::KeepRelative,
EAttachmentRule::KeepWorld,
EAttachmentRule::KeepRelative, false));
GroundPlane->SetMaterial(0,GroundPlaneMaterial);
GroundPlane->AttachToComponent(PreTravelPlatform, FAttachmentTransformRules(
EAttachmentRule::SnapToTarget,
EAttachmentRule::KeepWorld,
EAttachmentRule::KeepRelative,
true));
GroundVisualizationNiagaraComponent->SetAsset(GroundVisualizationNiagaraSystem);
HorizontalIndicator->AttachToComponent(PreTravelPlatform, FAttachmentTransformRules(
EAttachmentRule::SnapToTarget,
EAttachmentRule::SnapToTarget,
EAttachmentRule::KeepWorld,true));
VerticalIndicator->AttachToComponent(PreTravelPlatform, FAttachmentTransformRules(
EAttachmentRule::SnapToTarget,
EAttachmentRule::SnapToTarget,
EAttachmentRule::KeepWorld,true));
FVector HMDLocation = HMDPreview->GetComponentLocation();
HMDLocation.Z -= HeadBodyDistance;
BodyPreview->SetWorldLocation(HMDLocation);
//GroundVisualizationNiagaraComponent->SetNiagaraVariableFloat("User.BeamWidth", GroundConnectorWidth); // set default width*/
}
// Called every frame
void ATeleportVisualizer::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
......@@ -8,9 +8,20 @@
#include "NiagaraComponent.h"
#include "Kismet/GameplayStaticsTypes.h"
#include "Pawn/Navigation/MovementComponentBase.h"
#include "UI/TeleportVisualizer.h"
#include "TeleportationComponent.generated.h"
UENUM(BlueprintType)
enum class ETeleportState : uint8
{
BaseState UMETA(DisplayName = "Base/Idle State"),
HorizontalSelection UMETA(DisplayName = "Horizontal Location Selection"),
VerticalSelection UMETA(DisplayName = "Vertical Location Selection ")
};
UCLASS(Blueprintable)
class RWTHVRTOOLKIT_API UTeleportationComponent : public UMovementComponentBase
{
......@@ -27,6 +38,14 @@ public:
UPROPERTY(VisibleAnywhere, Category = "VR Movement|Teleport")
bool bUseNavMesh = false;
/**
* If true, target location will not get projected onto the geometry.
* Height of target location is defined in a second step, by holding the teleportation button
* and moving the controller up or down.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR Movement|Teleport")
bool bHeighTeleport = false;
/**
* Speed at which the projectile shoots out from the controller to get the teleport location
* Higher values = larger teleportation range
......@@ -35,7 +54,10 @@ public:
float TeleportLaunchSpeed = 800;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "VR Movement|Input|Actions")
UInputAction* Move;
UInputAction* Teleport;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "VR Movement|Input|Actions")
UInputAction* CancelTeleport;
// Trace Visualization
UPROPERTY(EditAnywhere)
......@@ -51,17 +73,33 @@ public:
UFUNCTION(BlueprintCallable)
void OnStartTeleportTrace(const FInputActionValue& Value);
void SetPreTravelInformationVisibility(bool bVisibility);
void SelectHorizontalLocation();
void SelectVerticalLocation();
float GetAngleBetweenVectors(FVector Vector1, FVector Vector2);
UFUNCTION(BlueprintCallable)
void UpdateTeleportTrace(const FInputActionValue& Value);
bool IsValidTeleportLocation(const FHitResult& Hit, FVector& ProjectedLocation) const;
UFUNCTION(BlueprintCallable)
void OnEndTeleportTrace(const FInputActionValue& Value);
UFUNCTION(BlueprintCallable)
void OnCancelTeleport(const FInputActionValue& Value);
bool IsValidTeleportLocation(const FHitResult& Hit, FVector& ProjectedLocation) const;
virtual void SetupPlayerInput(UInputComponent* PlayerInputComponent) override;
UPROPERTY(BlueprintReadOnly)
AActor* TeleportVisualizer;
ATeleportVisualizer* TeleportVisualizer;
void PlayHapticEffect(UHapticFeedbackEffect_Base* HapticEffect, float Intensity);
private:
UPROPERTY()
UMotionControllerComponent* TeleportationHand;
......@@ -72,8 +110,59 @@ private:
bool bTeleportTraceActive;
float TeleportProjectileRadius = 3.6;
float RotationArrowRadius = 10.0;
UPROPERTY()
FPredictProjectilePathResult PredictResult;
bool bValidTeleportLocation = false;
UPROPERTY()
FVector FinalTeleportLocation;
UPROPERTY()
float TwoStepThreshold = 0.99f;
void CleanupTeleportVisualization();
bool bTeleportCancelled = false;
void UpdateUserPreview();
UPROPERTY()
ETeleportState TeleportState = ETeleportState::BaseState;
UPROPERTY()
FVector ReferenceVector;
bool bHorizontalPhaseCompleted;
bool bHasVerticalPhaseStarted;
UPROPERTY()
float Deadzone = 10;
UPROPERTY()
float VelocityZone = 30;
UPROPERTY()
float ElevationSpeed = 6; // speed for height changes below the velocity zone
UPROPERTY()
float VelocitySpeed = 0.2; // speed for height changes in the velocity zone
UPROPERTY()
bool hasLeftDeadZone = false; // used to apply the deadzone limitation only when no height change has been made
UPROPERTY()
float HeightOffset = 0;
UPROPERTY()
float AngularOffset = 0;
UPROPERTY()
FVector SelectedHorizontalPosition;
UPROPERTY()
FPlane AngleProjectionPlane;
UPROPERTY()
bool bIsFirstHorizontalCall = true;
};
\ No newline at end of file
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "NiagaraComponent.h"
#include "Components/CapsuleComponent.h"
#include "GameFramework/Actor.h"
#include "TeleportVisualizer.generated.h"
UCLASS(Blueprintable)
class RWTHVRTOOLKIT_API ATeleportVisualizer : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ATeleportVisualizer();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
UPROPERTY(EditAnywhere)
UStaticMeshComponent* Platform;
UPROPERTY(EditAnywhere)
UCapsuleComponent* HorizontalCollisionChecker;
UPROPERTY(EditAnywhere)
UStaticMeshComponent* PreTravelPlatform;
/*UPROPERTY(EditAnywhere)
UStaticMesh* PlatformMesh;
UPROPERTY(EditAnywhere)
UStaticMesh* HMDPreviewMesh;
UPROPERTY(EditAnywhere)
UStaticMesh* BodyPreviewMesh;
UPROPERTY(EditAnywhere)
UStaticMesh* GroundPlaneMesh;*/
/*
UPROPERTY(EditAnywhere)
TSubclassOf<AActor> HorizontalIndicatorActor;
UPROPERTY(EditAnywhere)
TSubclassOf<AActor> VerticalIndicatorActor;
*/
UPROPERTY(EditAnywhere)
UNiagaraSystem* GroundVisualizationNiagaraSystem;
UPROPERTY(EditAnywhere)
UStaticMeshComponent* BodyPreview;
UPROPERTY(EditAnywhere)
UStaticMeshComponent* HMDPreview;
UPROPERTY(EditAnywhere)
UStaticMeshComponent* GroundPlane;
UPROPERTY(EditAnywhere)
UMaterialInterface* GroundPlaneMaterial;
UPROPERTY(EditAnywhere)
UNiagaraComponent* GroundVisualizationNiagaraComponent;
float DefaultHorizontalRange;
UPROPERTY(EditAnywhere)
float TwoStepDeadZone = 0.1f;
// float determining the distance between the HMD Preview mesh and the BodyPreviewMesh
UPROPERTY(EditAnywhere)
float HeadBodyDistance = 55;
UPROPERTY(EditAnywhere)
UHapticFeedbackEffect_Base* HapticFeedback;
UMaterialInstanceDynamic* DynamicVerticalIndicatorMaterial;
UPROPERTY(EditAnywhere)
UChildActorComponent* HorizontalIndicator;
UPROPERTY(EditAnywhere)
UChildActorComponent* VerticalIndicator;
private:
float GroundConnectorHeight = 100; // The threshold for how far above the ground a ground visualization should be visualized
float GroundConnectorWidth = 60.f; // determines how wide the ground connection visualization should be
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment