4#include "Components/StaticMeshComponent.h"
5#include "Components/WidgetInteractionComponent.h"
6#include "Kismet/GameplayStatics.h"
7#include "NavigationSystem.h"
8#include "VRExpansionFunctionLibrary.h"
12#include "Kismet/KismetMathLibrary.h"
14#define TELEPORT_DEBUG 0
19 : TeleportCylinder(nullptr)
21 , bDrawTeleportCylinder(true)
22 , TeleportFadeColor(FLinearColor::Black)
23 , NavigationSystem(nullptr)
25 static ConstructorHelpers::FObjectFinder<UStaticMesh> CylinderMeshFinder(TEXT(
"StaticMesh'/PixoCore/Meshes/BasicShapes/Cylinder.Cylinder'"));
26 UStaticMesh* CylinderMesh = CylinderMeshFinder.Object;
28 static ConstructorHelpers::FObjectFinder<UStaticMesh> CylinderRingMeshFinder(TEXT(
"StaticMesh'/PixoCore/Meshes/Controller/SM_FatCylinder.SM_FatCylinder'"));
29 UStaticMesh* CylinderRingMesh = CylinderRingMeshFinder.Object;
31 static ConstructorHelpers::FObjectFinder<UMaterialInstance> TeleportCylinderMaterialFinder(TEXT(
"MaterialInstanceConstant'/PixoCore/Materials/Controller/TeleportCylinderPreviewMaterialInstance.TeleportCylinderPreviewMaterialInstance'"));
32 UMaterialInstance* CylinderMaterial = TeleportCylinderMaterialFinder.Object;
34 static ConstructorHelpers::FObjectFinder<UMaterial> ArcEndPointMaterialFinder(TEXT(
"Material'/PixoCore/Materials/Controller/ArcEndpointMaterial.ArcEndpointMaterial'"));
35 UMaterial* ArcEndPointMaterial = ArcEndPointMaterialFinder.Object;
38 TeleportCylinder = CreateDefaultSubobject<UStaticMeshComponent>(TEXT(
"TeleportCylinder"));
43 TeleportCylinder->SetCollisionProfileName(UCollisionProfile::NoCollision_ProfileName);
48 Ring = CreateDefaultSubobject<UStaticMeshComponent>(TEXT(
"Ring"));
50 Ring->SetRelativeScale3D(FVector(0.5f, 0.5f, 0.15f));
51 Ring->SetStaticMesh(CylinderRingMesh);
52 Ring->SetMaterial(0, ArcEndPointMaterial);
53 Ring->SetCollisionProfileName(UCollisionProfile::NoCollision_ProfileName);
54 Ring->SetGenerateOverlapEvents(
false);
59 Super::ActivateTeleporter(InActivate);
74 NavigationSystem = FNavigationSystem::GetCurrent<UNavigationSystemV1>(GetWorld());
79 TArray<FVector> TracePoints;
82 FVector TraceLocation;
85 FVector NavMeshLocation;
118 FVector DevicePosition = FVector::ZeroVector;
119 FRotator DeviceRotation = FRotator::ZeroRotator;
120 UHeadMountedDisplayFunctionLibrary::GetOrientationAndPosition(DeviceRotation, DevicePosition);
121 DevicePosition.Z = 0.0f;
122 FVector Correction = UKismetMathLibrary::GreaterGreater_VectorRotator(DevicePosition,
TeleportRotation);
124 FVector HMDPositionInWorldSpace = GetOwner()->GetActorLocation() - DevicePosition;
126 HMDPositionInWorldSpace = PixoVRCharacter->GetVRLocation();
127 HMDPositionInWorldSpace.Z = 30.0f;
128 FVector OwnerActorLocation = GetOwner()->GetActorLocation();
129 OwnerActorLocation.Z += 10.0f;
130 UKismetSystemLibrary::DrawDebugLine(
this, OwnerActorLocation,
TeleportCylinder->GetComponentLocation(), FColor::Red, 0.0f, 2.0f);
131 UKismetSystemLibrary::DrawDebugLine(
this, OwnerActorLocation, HMDPositionInWorldSpace, FColor::Green, 0.0f, 2.0f);
137 FVector StartPos(FVector::ZeroVector);
138 FVector LaunchVelocity (FVector::ZeroVector);
143 TArray<TEnumAsByte<EObjectTypeQuery>> ObjectTypes;
144 ObjectTypes.Add(UEngineTypes::ConvertToObjectType(ECC_WorldStatic));
146 FPredictProjectilePathParams Params;
147 Params.bTraceWithCollision =
true;
148 Params.bTraceComplex =
false;
149 Params.DrawDebugType = EDrawDebugTrace::None;
150 Params.DrawDebugTime = 0.0f;
151 Params.SimFrequency = 30.0f;
152 Params.OverrideGravityZ = 0.0f;
153 Params.ObjectTypes = ObjectTypes;
154 Params.bTraceWithChannel =
false;
155 Params.ProjectileRadius = 0.0f;
156 Params.StartLocation = StartPos;
157 Params.MaxSimTime = 2.0f;
158 Params.LaunchVelocity = LaunchVelocity;
160 FPredictProjectilePathResult PredictResult;
161 bool bHit = UGameplayStatics::PredictProjectilePath(
this, Params, PredictResult);
163 FHitResult HitResult;
164 FVector LastTraceDestination;
166 HitResult = PredictResult.HitResult;
167 LastTraceDestination = PredictResult.LastTraceDestination.Location;
168 TracePoints.Empty(PredictResult.PathData.Num());
170 for (
const FPredictProjectilePathPointData& PathPoint : PredictResult.PathData)
172 TracePoints.Add(PathPoint.Location);
175 TraceLocation = HitResult.Location;
177 bool bProjectPointToNavigation =
false;
180 FVector QueryingExtent (500.0f, 500.0f, 500.0f);
181 FNavLocation NavLocation {};
183 bProjectPointToNavigation =
NavigationSystem->ProjectPointToNavigation(HitResult.Location, NavLocation, QueryingExtent);
184 NavMeshLocation = NavLocation.Location;
187 bProjectPointToNavigation = (NavMeshLocation != FVector(0.0f, 0.0f, 0.0f)) && (TraceLocation != NavMeshLocation);
189 return bHit & bProjectPointToNavigation;
194 if(ValidLocationFound)
196 const auto Start = NavMeshLocation;
197 const auto End = Start + FVector(0.0f, 0.0f, -200.0f);
198 TArray<TEnumAsByte<EObjectTypeQuery>> ObjectTypes;
199 ObjectTypes.Add(UEngineTypes::ConvertToObjectType(ECC_WorldStatic));
200 const auto TraceComplex =
false;
201 const TArray<AActor*> ActorsToIgnore;
202 const auto IgnoreSelf =
true;
203 FHitResult HitResult;
204 const float DrawTime = 5.0;
206 UKismetSystemLibrary::LineTraceSingleForObjects(
this,
212 EDrawDebugTrace::None,
219 FVector NewLocation = FVector::ZeroVector;
220 if(HitResult.bBlockingHit)
222 NewLocation = HitResult.ImpactPoint;
226 NewLocation = NavMeshLocation;
229 TeleportCylinder->SetWorldLocation(NewLocation,
false,
nullptr, ETeleportType::TeleportPhysics);
238void APixoVRTeleporter::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
240 if(PropertyChangedEvent.Property !=
nullptr)
242 const FName PropertyName (PropertyChangedEvent.Property->GetFName());
249 Super::PostEditChangeProperty(PropertyChangedEvent);
272 const FVector PivotPoint = VRLocation;
273 const FVector InvPivotPoint = UKismetMathLibrary::InverseTransformLocation(ActorTransform, PivotPoint);
275 const FVector LastValidTeleportLocation =
TeleportCylinder->GetComponentLocation();
278 UVRExpansionFunctionLibrary::RotateAroundPivot(FRotator::ZeroRotator, TeleportToLocation, ActorRotation, InvPivotPoint,
TimedLocation,
TimedRotation,
true);
280 auto FadeInFinishedEvent = [
this]()
DEFINE_LOG_CATEGORY(LogPixoVRTeleporter)
Pixo VR Character This class represents the main character in the Pixo VR game. It extends the AVRCha...
USoundCue * TeleportSoundCue
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "PixoVR", meta = (EditCondition = "bTeleportSo...
bool bTeleportSoundsEnabled
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "PixoVR")
Class for VR teleporter functionality. It allows teleportation using visual indicators.
virtual void BeginPlay() override
virtual void TickTeleporter(float DeltaTime) override
Tick the Teleporter.
virtual void ExecuteTeleportation(UVRBaseCharacterMovementComponent *MovementComponent, const FTransform &ActorTransform, const FVector &VRLocation, const FRotator &ActorRotation) override
Execute the teleportation. It checks if there is a valid teleport destination before executing the te...
bool bDrawTeleportCylinder
UPROPERTY(EditAnywhere, Category = "PixoVR | Teleporter")
virtual void ActivateTeleporter(bool InActivate) override
Activate or deactivate the Teleporter.
UStaticMeshComponent * TeleportCylinder
UPROPERTY(VisibleDefaultsOnly, BlueprintReadWrite)
UStaticMeshComponent * Ring
UPROPERTY(VisibleDefaultsOnly, BlueprintReadWrite)
UVRBaseCharacterMovementComponent * MovementComponent
void UpdateTeleportCylinder(const FVector &NewLocation, bool ValidLocationFound)
Update the teleport cylinder.
bool TraceTeleportDestination(TArray< FVector > &TracePoints, FVector &TraceLocation, FVector &NavMeshLocation)
Traces the teleport destination using projectile path prediction and navigation system....
UNavigationSystemV1 * NavigationSystem
float TeleportLaunchVelocity
UPROPERTY(EditAnywhere, Category = "PixoVR | Teleporter")
bool bIsValidTeleportDestination
UPROPERTY(BlueprintReadOnly, Category = "PixoVR | Teleporter")
UStaticMeshComponent * Arrow
UPROPERTY(VisibleDefaultsOnly, BlueprintReadWrite)
FRotator PadRotation
UPROPERTY(BlueprintReadOnly, Category = "PixoVR | Teleporter")
float FadeInDuration
UPROPERTY(EditAnywhere, Category = "PiUpdateMotionControllerRotationxoVR | Teleporter")
bool bDrawTeleportArrow
UPROPERTY(EditAnywhere, Category = "PixoVR | Teleporter")
float FadeOutDuration
UPROPERTY(EditAnywhere, Category = "PixoVR | Teleporter")
virtual void FVector GetTeleportDestination(const FVector &OriginalLocation)
Get the teleport destination.
void GetTeleportationTransform(FVector &Location, FVector &ForwardVector)
Get the teleportation transform which includes location and orientation.
virtual void UpdateArcEndpoint(const FVector &NewLocation, bool ValidLocationFound)
Update the endpoint of the arc spline.
virtual void UpdateArcSpline(TArray< FVector > &SplinePoints, bool ValidLocationFound)
Update the arc spline.
FRotator TeleportRotation
UPROPERTY(BlueprintReadOnly, Category = "PixoVR | Teleporter")
bool bDrawArcSpline
UPROPERTY(EditAnywhere, Category = "PixoVR | Teleporter")
static FUNCTION_NON_NULL_RETURN_START TEventType * NewEvent(APlayerController *Executor=nullptr) FUNCTION_NON_NULL_RETURN_END
Creates a new event of the specified type.