A Demo Project for the UnrealEngineSDK
Loading...
Searching...
No Matches
VRPlayerStart.h
Go to the documentation of this file.
1#pragma once
2
3#include "CoreMinimal.h"
4#include "UObject/ObjectMacros.h"
5#include "GameFramework/PlayerStart.h"
6#include "Engine/NavigationObjectBase.h"
7#include "Components/SceneComponent.h"
8#include "Components/CapsuleComponent.h"
9#include "Components/BillboardComponent.h"
10#include "VRPlayerStart.generated.h"
11
16UCLASS(Blueprintable, ClassGroup = Common, hidecategories = Collision)
17class VREXPANSIONPLUGIN_API AVRPlayerStart : public APlayerStart
18{
19 GENERATED_BODY()
21private:
22 UPROPERTY()
23 class USceneComponent* VRRootComp;
24public:
25
26 AVRPlayerStart(const FObjectInitializer& ObjectInitializer);
27
29 class USceneComponent* GetVRRootComponent() const { return VRRootComp; }
30
31 // Override this to use capsule even if it isn't the root component
32 virtual void GetSimpleCollisionCylinder(float& CollisionRadius, float& CollisionHalfHeight) const override
33 {
34 UCapsuleComponent * CapsuleComp = GetCapsuleComponent();
35 if (CapsuleComp != nullptr && CapsuleComp->IsRegistered() && CapsuleComp->IsCollisionEnabled())
36 {
37 // Note: assuming vertical orientation
38 CapsuleComp->GetScaledCapsuleSize(CollisionRadius, CollisionHalfHeight);
39 }
40 else
41 {
42 Super::GetSimpleCollisionCylinder(CollisionRadius, CollisionHalfHeight);
43 }
44 }
45
46 void FindBase() override
47 {
48 if (GetWorld()->HasBegunPlay())
49 {
50 return;
51 }
52
53 if (ShouldBeBased())
54 {
55 UCapsuleComponent * CapsuleComp = GetCapsuleComponent();
56 if (!CapsuleComp)
57 return;
58
59 // not using find base, because don't want to fail if LD has navigationpoint slightly interpenetrating floor
60 FHitResult Hit(1.f);
61
62 const float Radius = CapsuleComp->GetScaledCapsuleRadius();
63 FVector const CollisionSlice(Radius, Radius, 1.f);
64
65 // check for placement
66 float ScaledHalfHeight = CapsuleComp->GetScaledCapsuleHalfHeight();
67 const FVector TraceStart = GetActorLocation() + FVector(0.f, 0.f, ScaledHalfHeight);
68 const FVector TraceEnd = GetActorLocation() - FVector(0.f, 0.f, 2.f * ScaledHalfHeight);
69
70 GetWorld()->SweepSingleByObjectType(Hit, TraceStart, TraceEnd, FQuat::Identity, FCollisionObjectQueryParams(ECC_WorldStatic), FCollisionShape::MakeBox(CollisionSlice), FCollisionQueryParams(SCENE_QUERY_STAT(NavFindBase), false));
71
72 // @fixme, ensure object is on the navmesh?
73 // if( Hit.Actor != NULL )
74 // {
75 // if (Hit.Normal.Z > Scout->WalkableFloorZ)
76 // {
77 // const FVector HitLocation = TraceStart + (TraceEnd - TraceStart) * Hit.Time;
78 // TeleportTo(HitLocation + FVector(0.f,0.f,CapsuleComponent->GetScaledCapsuleHalfHeight()-2.f), GetActorRotation(), false, true);
79 // }
80 // else
81 // {
82 // Hit.Actor = NULL;
83 // }
84 // }
85
86 if (GetGoodSprite())
87 {
88 GetGoodSprite()->SetVisibility(true);
89 }
90 if (GetBadSprite())
91 {
92 GetBadSprite()->SetVisibility(false);
93 }
94 }
95 }
96
97
98 void Validate() override
99 {
100 if (ShouldBeBased() && (GetGoodSprite() || GetBadSprite()))
101 {
102 UCapsuleComponent * CapsuleComp = GetCapsuleComponent();
103 if (!CapsuleComp)
104 return;
105
106 FVector OrigLocation = GetActorLocation();
107 const float Radius = CapsuleComp->GetScaledCapsuleRadius();
108 FVector const Slice(Radius, Radius, 1.f);
109
110 bool bResult = true;
111
112 // Check for adjustment
113 FHitResult Hit(ForceInit);
114 float ScaledHalfHeight = CapsuleComp->GetScaledCapsuleHalfHeight();
115 const FVector TraceStart = GetActorLocation() + FVector(0.f, 0.f, ScaledHalfHeight);
116 const FVector TraceEnd = GetActorLocation() - FVector(0.f, 0.f, 4.f * ScaledHalfHeight);
117 GetWorld()->SweepSingleByChannel(Hit, TraceStart, TraceEnd, FQuat::Identity, ECC_Pawn, FCollisionShape::MakeBox(Slice), FCollisionQueryParams(SCENE_QUERY_STAT(NavObjectBase_Validate), false, this));
118 if (Hit.bBlockingHit)
119 {
120 const FVector HitLocation = TraceStart + (TraceEnd - TraceStart) * Hit.Time;
121 FVector Dest = HitLocation - FVector(0.f, 0.f, /*CapsuleComponent->GetScaledCapsuleHalfHeight() -*/ 2.f);
122
123 // Move actor (TEST ONLY) to see if navigation point moves
124 TeleportTo(Dest, GetActorRotation(), false, true);
125
126 // If only adjustment was down towards the floor, then it is a valid placement
127 FVector NewLocation = GetActorLocation();
128 bResult = (NewLocation.X == OrigLocation.X &&
129 NewLocation.Y == OrigLocation.Y &&
130 NewLocation.Z <= OrigLocation.Z);
131
132 // Move actor back to original position
133 TeleportTo(OrigLocation, GetActorRotation(), false, true);
134 }
135
136 // Update sprites by result
137 if (GetGoodSprite())
138 {
139 GetGoodSprite()->SetVisibility(bResult);
140 }
141 if (GetBadSprite())
142 {
143 GetBadSprite()->SetVisibility(!bResult);
144 }
145 }
146
147 // Force update of icon
148 MarkComponentsRenderStateDirty();
149 }
150};
UCLASS(Blueprintable, ClassGroup = Common, hidecategories = Collision)
void Validate() override
class USceneComponent * VRRootComp
UPROPERTY()
virtual void GetSimpleCollisionCylinder(float &CollisionRadius, float &CollisionHalfHeight) const override
void FindBase() override
class USceneComponent * GetVRRootComponent() const