Documentation for the Unreal C++ Plugin
Loading...
Searching...
No Matches
TeleporterBase.cpp
Go to the documentation of this file.
1// Copyright(c) 2018 PixoVR, LLC. All Rights Reserved.
2
3
5
6#include "PixoVRCharacter.h"
7
8
9// Sets default values
11 : MotionController(nullptr)
12 , bIsTeleporterActive(false)
13 , bIsValidTeleportDestination(false)
14 , bDrawArcSpline(true)
15 , bDrawTeleportArrow(false)
16 , TeleportLaunchVelocity(1200.f)
17 , TeleportRotation(FRotator::ZeroRotator)
18 , PadRotation(FRotator::ZeroRotator)
19 , FadeInDuration(0.25f)
20 , FadeOutDuration(0.25f)
21 , ThumbDeadZone(0.5f)
22 {
23 PrimaryActorTick.bCanEverTick = true;
24 PrimaryActorTick.bStartWithTickEnabled = false;
25
26 bReplicates = true;
27 SetReplicateMovement(false);
28 bNetLoadOnClient = false;
29
30 static ConstructorHelpers::FObjectFinder<UStaticMesh> ArcSplineMeshFinder(TEXT("StaticMesh'/PixoCore/Meshes/Controller/BeamMesh.BeamMesh'"));
31 ArcSplineMesh = ArcSplineMeshFinder.Object;
32
33 static ConstructorHelpers::FObjectFinder<UMaterial> ArcSplineMaterialFinder(TEXT("Material'/PixoCore/Materials/Controller/SplineArcMaterial.SplineArcMaterial'"));
34 ArcSplineMaterial = ArcSplineMaterialFinder.Object;
35
36 static ConstructorHelpers::FObjectFinder<UStaticMesh> ArcEndPointMeshFinder(TEXT("StaticMesh'/PixoCore/Meshes/BasicShapes/Sphere.Sphere'"));
37 UStaticMesh* ArcEndPointMesh = ArcEndPointMeshFinder.Object;
38
39 static ConstructorHelpers::FObjectFinder<UMaterial> ArcEndPointMaterialFinder(TEXT("Material'/PixoCore/Materials/Controller/ArcEndpointMaterial.ArcEndpointMaterial'"));
40 UMaterial* ArcEndPointMaterial = ArcEndPointMaterialFinder.Object;
41
42 USceneComponent* SceneComponent = CreateDefaultSubobject<USceneComponent>(TEXT("TeleportSceneComponent"));
43 RootComponent = SceneComponent;
44
45 // Arc Spline.
46 ArcSplineComponent = CreateDefaultSubobject<USplineComponent>(TEXT("ArcSpline"));
47 ArcSplineComponent->SetupAttachment(SceneComponent);
48 ArcSplineComponent->SetWorldLocation(FVector(12.53f, -1.76f, 2.55f));
49
50 // Arc Endpoint.
51 ArcEndPoint = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ArcEndPoint"));
52 ArcEndPoint->SetupAttachment(SceneComponent);
53 ArcEndPoint->SetWorldScale3D(FVector(0.08f, 0.08f, 0.08f));
54 ArcEndPoint->SetStaticMesh(ArcEndPointMesh);
55 ArcEndPoint->SetMaterial(0, ArcEndPointMaterial);
56 ArcEndPoint->SetVisibility(false, true);
57 ArcEndPoint->SetCollisionProfileName(UCollisionProfile::NoCollision_ProfileName);
58 ArcEndPoint->SetGenerateOverlapEvents(false);
59 ArcEndPoint->SetAbsolute(true, true, true);
60
61 // Teleport Cylinder Arrow.
62 static ConstructorHelpers::FObjectFinder<UStaticMesh> CylinderArrowMeshFinder(TEXT("StaticMesh'/PixoCore/Meshes/Controller/BeaconDirection.BeaconDirection'"));
63 UStaticMesh* CylinderArrowMesh = CylinderArrowMeshFinder.Object;
64
65 Arrow = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Arrow"));
66 Arrow->SetupAttachment(SceneComponent);
67 Arrow->SetStaticMesh(CylinderArrowMesh);
68 Arrow->SetMaterial(0, ArcEndPointMaterial);
69 Arrow->SetCollisionProfileName(UCollisionProfile::NoCollision_ProfileName);
70 Arrow->SetGenerateOverlapEvents(false);
71 Arrow->SetVisibility(false, true);
72}
73
74// Called when the game starts or when spawned
76{
77 Super::BeginPlay();
78}
79
80void ATeleporterBase::Tick(float DeltaTime)
81{
82 Super::Tick(DeltaTime);
83
85 {
86 TickTeleporter(DeltaTime);
87 }
88}
89
90void ATeleporterBase::UpdateArcSpline(TArray<FVector>& SplinePoints, bool ValidLocationFound)
91{
92 ArcSplineComponent->ClearSplinePoints(true);
93
94 if(ValidLocationFound)
95 {
96 for(auto& SplinePoint : SplinePoints)
97 {
98 ArcSplineComponent->AddSplinePoint(SplinePoint, ESplineCoordinateSpace::Local, true);
99 }
100
101 ArcSplineComponent->SetSplinePointType(SplinePoints.Num() - 1, ESplinePointType::CurveClamped, true);
102
103 if(SplineMeshComponents.Num() < ArcSplineComponent->GetNumberOfSplinePoints())
104 {
105 const int32 NumberOfSplinesToAdd = (ArcSplineComponent->GetNumberOfSplinePoints() - 1) - SplineMeshComponents.Num();
106
107 for(int32 Index = 0; Index <= NumberOfSplinesToAdd; Index++)
108 {
109 USplineMeshComponent* SplineMeshComponent = NewObject<USplineMeshComponent>(this);
110
111 SplineMeshComponent->SetMobility(EComponentMobility::Movable);
112 SplineMeshComponent->SetStartPosition(FVector(0.0f, 0.0f, 0.0f), true);
113 SplineMeshComponent->SetStartTangent(FVector(100.0f, 0.0f, 0.0f), true);
114 SplineMeshComponent->SetEndPosition(FVector(100.0f, 0.0f, 0.0f), true);
115 SplineMeshComponent->SetEndTangent(FVector(100.0f, 0.0f, 0.0f), true);
116 SplineMeshComponent->SetSplineUpDir(FVector(0.0f, 0.0f, 1.0f), true);
117 SplineMeshComponent->SetForwardAxis(ESplineMeshAxis::X, true);
118 SplineMeshComponent->SetStartScale(FVector2D(4, 4));
119 SplineMeshComponent->SetEndScale(FVector2D(4, 4));
120 SplineMeshComponent->SetStaticMesh(ArcSplineMesh);
121 SplineMeshComponent->SetMaterial(0, ArcSplineMaterial);
122 SplineMeshComponent->SetCollisionEnabled(ECollisionEnabled::NoCollision);
123 SplineMeshComponent->SetGenerateOverlapEvents(false);
124
125 FTransform Transform = FTransform(FRotator(0.0f, 0.0f, 0.0f), FVector(0.0f, 0.0f, 0.0f), FVector(1.0f, 1.0f, 1.0f));
126 SplineMeshComponent->SetRelativeTransform(Transform);
127 SplineMeshComponent->RegisterComponent();
128
129 SplineMeshComponents.Add(SplineMeshComponent);
130 }
131 }
132
133 // Update the start/end points of the spline components.
134 for(int32 Index = 0; Index < SplineMeshComponents.Num(); Index++)
135 {
136 USplineMeshComponent* SplineMeshComponent = SplineMeshComponents[Index];
137
138 if(Index < (ArcSplineComponent->GetNumberOfSplinePoints() - 1))
139 {
140 SplineMeshComponent->SetVisibility(true, false);
141
142 const auto StartTangent = ArcSplineComponent->GetTangentAtSplinePoint(Index, ESplineCoordinateSpace::Local);
143 const auto EndTangent = ArcSplineComponent->GetTangentAtSplinePoint(Index + 1, ESplineCoordinateSpace::Local);
144
145 SplineMeshComponent->SetStartAndEnd(SplinePoints[Index], StartTangent, SplinePoints[Index + 1], EndTangent, true);
146 }
147 else
148 {
149 // Unused spline components we better hide.
150 SplineMeshComponent->SetVisibility(false, false);
151 }
152 }
153 }
154 else
155 {
156 // TODO For now we just hide all splines when we don't have a valid teleport location.
157 for(int32 Index = 0; Index < SplineMeshComponents.Num(); Index++)
158 {
159 USplineMeshComponent* SplineMeshComponent = SplineMeshComponents[Index];
160 SplineMeshComponent->SetVisibility(false, false);
161 }
162 }
163}
164
166{
167 for(const auto& SplineMeshComponent : SplineMeshComponents)
168 {
169 SplineMeshComponent->DestroyComponent();
170 }
171
172 SplineMeshComponents.Empty();
173
174 ArcSplineComponent->ClearSplinePoints(true);
175}
176
178{
179 Super::Destroyed();
180
181 ClearArc();
182}
183
185{
186 if(InActivate == bIsTeleporterActive)
187 {
188 return;
189 }
190
191 bIsTeleporterActive = InActivate;
192
193 // Enable/Disable ticking for this actor.
194 SetActorTickEnabled(bIsTeleporterActive);
195
196 // Hide/Show the arc splines.
197 ArcSplineComponent->SetVisibility(InActivate && bDrawArcSpline, true);
198
199 // Handle visibility of the arrow if it is enabled.
200 Arrow->SetVisibility(InActivate && bDrawTeleportArrow, true);
201
202 // The ArchEndPoint is activated inside UpdateArchEndPoint. We deactivate definitely when
203 // InActivate = false.
204 if(!InActivate)
205 {
206 ArcEndPoint->SetVisibility(false, false);
207 ClearArc();
208 }
209}
210
215
216void ATeleporterBase::UpdateArcEndpoint(const FVector& NewLocation, bool ValidLocationFound)
217{
218 ArcEndPoint->SetVisibility(ValidLocationFound, true);
219 ArcEndPoint->SetWorldLocation(NewLocation, false, nullptr, ETeleportType::TeleportPhysics);
220}
221
222FVector ATeleporterBase::GetTeleportDestination(const FVector& OriginalLocation)
223{
224 APixoVRCharacter* PixoVRCharacter = Cast<APixoVRCharacter>(GetOwner());
225 FVector Offset = PixoVRCharacter->VRRootReference->OffsetComponentToWorld.GetLocation() - PixoVRCharacter->GetActorLocation();
226 Offset.Z = 0.0f;
227 return OriginalLocation - Offset;
228}
229
230void ATeleporterBase::GetTeleportationTransform(FVector& Location, FVector& ForwardVector)
231{
232 Location = RootComponent->GetComponentLocation();
233 ForwardVector = RootComponent->GetForwardVector();
234}
235
236void ATeleporterBase::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
237{
238 Super::GetLifetimeReplicatedProps(OutLifetimeProps);
239
240 DOREPLIFETIME(ATeleporterBase, MotionController);
241}
242
243void ATeleporterBase::UpdateMotionControllerRotation(const FVector2D& Direction)
244{
246 {
247 return;
248 }
249
251}
252
253FRotator ATeleporterBase::GetRotationFromInput(const FVector2D& Direction)
254{
255 // Rotate input X+Y always point forward relative to the current pawn rotation.
256 FVector A(Direction.X, Direction.Y, 0.0f);
257
258 // We should normalize the vector.
259 A.Normalize();
260
261 // Check whether thumb in near center (ignore rotation overrides).
262 const bool Condition = A.Size() > ThumbDeadZone;
263 if(Condition)
264 {
265 FRotator CharacterRotation = GetOwner()->GetActorRotation();
266 CharacterRotation.Roll = 0.0f;
267 CharacterRotation.Pitch = 0.0f;
268
269 const FVector RotatedVector = CharacterRotation.RotateVector(A);
270 return RotatedVector.Rotation();
271 }
272
273 return FRotator::ZeroRotator;
274}
275
276void ATeleporterBase::SetMotionController(UGripMotionControllerComponent* InMotionController)
277{
278 MotionController = InMotionController;
279}
Pixo VR Character This class represents the main character in the Pixo VR game. It extends the AVRCha...
UCLASS(Abstract)
USplineComponent * ArcSplineComponent
UPROPERTY(VisibleDefaultsOnly, BlueprintReadWrite)
UStaticMeshComponent * ArcEndPoint
UPROPERTY(VisibleDefaultsOnly, BlueprintReadWrite)
UStaticMeshComponent * Arrow
UPROPERTY(VisibleDefaultsOnly, BlueprintReadWrite)
virtual void ActivateTeleporter(bool InActivate)
Activate or deactivate the Teleporter.
FRotator GetRotationFromInput(const FVector2D &Direction)
Calculate the FRotator from the pad of a controller.
FRotator PadRotation
UPROPERTY(BlueprintReadOnly, Category = "PixoVR | Teleporter")
bool bIsTeleporterActive
UPROPERTY(BlueprintReadOnly, Category = "PixoVR | Teleporter")
virtual void BeginPlay() override
virtual bool IsActivated()
Check if the teleporter is activated.
UStaticMesh * ArcSplineMesh
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PixoVR | Teleporter", Meta = (AllowPrivateAcc...
virtual void SetMotionController(UGripMotionControllerComponent *InMotionController)
Set the motion controller that controls this Teleport.
UGripMotionControllerComponent * MotionController
UPROPERTY(Replicated)
bool bDrawTeleportArrow
UPROPERTY(EditAnywhere, Category = "PixoVR | Teleporter")
TArray< USplineMeshComponent * > SplineMeshComponents
UMaterial * ArcSplineMaterial
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PixoVR | Teleporter", Meta = (AllowPrivateAcc...
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 virtual void ClearArc()
Clear the arc spline.
virtual void Tick(float DeltaTime) override
virtual void Destroyed() override
virtual void UpdateMotionControllerRotation(const FVector2D &Direction)
Update the motion controller rotation for pad rotation.
virtual void UpdateArcSpline(TArray< FVector > &SplinePoints, bool ValidLocationFound)
Update the arc spline.
virtual void GetLifetimeReplicatedProps(TArray< FLifetimeProperty > &OutLifetimeProps) const override
virtual void TickTeleporter(float DeltaTime) PURE_VIRTUAL(
Tick the Teleporter.
float ThumbDeadZone
UPROPERTY(EditAnywhere, Category = "PixoVR | Teleporter")
bool bDrawArcSpline
UPROPERTY(EditAnywhere, Category = "PixoVR | Teleporter")