A Demo Project for the UnrealEngineSDK
Loading...
Searching...
No Matches
VRBaseCharacter.cpp
Go to the documentation of this file.
1// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
2
3#include "VRBaseCharacter.h"
5#include "NavigationSystem.h"
7//#include "Runtime/Engine/Private/EnginePrivate.h"
8
9DEFINE_LOG_CATEGORY(LogBaseVRCharacter);
10
11FName AVRBaseCharacter::LeftMotionControllerComponentName(TEXT("Left Grip Motion Controller"));
12FName AVRBaseCharacter::RightMotionControllerComponentName(TEXT("Right Grip Motion Controller"));
13FName AVRBaseCharacter::ReplicatedCameraComponentName(TEXT("VR Replicated Camera"));
14FName AVRBaseCharacter::ParentRelativeAttachmentComponentName(TEXT("Parent Relative Attachment"));
16FName AVRBaseCharacter::VRProxyComponentName(TEXT("VRProxy"));
17
18
20: Super()
21{
22 bJustTeleported = false;
24 bPausedTracking = false;
25 PausedTrackingLoc = FVector::ZeroVector;
27 Owner = nullptr;
28}
29
30AVRBaseCharacter::AVRBaseCharacter(const FObjectInitializer& ObjectInitializer)
31 : Super(ObjectInitializer/*.DoNotCreateDefaultSubobject(ACharacter::MeshComponentName)*/.SetDefaultSubobjectClass<UVRBaseCharacterMovementComponent>(ACharacter::CharacterMovementComponentName))
32
33{
34
35 FRepMovement& MovementRep = GetReplicatedMovement_Mutable();
36
37 // Remove the movement jitter with slow speeds
38 MovementRep.LocationQuantizationLevel = EVectorQuantization::RoundTwoDecimals;
39
40 if (UCapsuleComponent * cap = GetCapsuleComponent())
41 {
42 cap->SetCapsuleSize(16.0f, 96.0f);
43 cap->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore);
44 cap->SetCollisionResponseToChannel(ECollisionChannel::ECC_WorldStatic, ECollisionResponse::ECR_Block);
45 }
46
47 NetSmoother = CreateDefaultSubobject<USceneComponent>(AVRBaseCharacter::SmoothingSceneParentComponentName);
48 if (NetSmoother)
49 {
50 NetSmoother->SetupAttachment(RootComponent);
51 }
52
53 VRProxyComponent = CreateDefaultSubobject<USceneComponent>(AVRBaseCharacter::VRProxyComponentName);
55 {
56 VRProxyComponent->SetupAttachment(NetSmoother);
57 }
58
59 VRReplicatedCamera = CreateDefaultSubobject<UReplicatedVRCameraComponent>(AVRBaseCharacter::ReplicatedCameraComponentName);
61 {
63 VRReplicatedCamera->SetupAttachment(VRProxyComponent);
65 }
66
68 if (GetMovementComponent())
69 {
70 VRMovementReference = Cast<UVRBaseCharacterMovementComponent>(GetMovementComponent());
71 //AddTickPrerequisiteComponent(this->GetCharacterMovement());
72 }
73
74 ParentRelativeAttachment = CreateDefaultSubobject<UParentRelativeAttachmentComponent>(AVRBaseCharacter::ParentRelativeAttachmentComponentName);
76 {
77 // Moved this to be root relative as the camera late updates were killing how it worked
80 ParentRelativeAttachment->AddTickPrerequisiteComponent(VRReplicatedCamera);
81
82 if (USkeletalMeshComponent * SKMesh = GetMesh())
83 {
84 SKMesh->SetupAttachment(ParentRelativeAttachment);
85 }
86 }
87
88 LeftMotionController = CreateDefaultSubobject<UGripMotionControllerComponent>(AVRBaseCharacter::LeftMotionControllerComponentName);
90 {
91 LeftMotionController->SetupAttachment(VRProxyComponent);
92 //LeftMotionController->MotionSource = FXRMotionControllerBase::LeftHandSourceId;
93 LeftMotionController->SetTrackingMotionSource(FXRMotionControllerBase::LeftHandSourceId);
94 //LeftMotionController->Hand = EControllerHand::Left;
96 //LeftMotionController->bUpdateInCharacterMovement = true;
97 // Keep the controllers ticking after movement
98 LeftMotionController->AddTickPrerequisiteComponent(GetCharacterMovement());
100 }
101
102 RightMotionController = CreateDefaultSubobject<UGripMotionControllerComponent>(AVRBaseCharacter::RightMotionControllerComponentName);
104 {
105 RightMotionController->SetupAttachment(VRProxyComponent);
106 //RightMotionController->MotionSource = FXRMotionControllerBase::RightHandSourceId;
107 RightMotionController->SetTrackingMotionSource(FXRMotionControllerBase::RightHandSourceId);
108 //RightMotionController->Hand = EControllerHand::Right;
110 //RightMotionController->bUpdateInCharacterMovement = true;
111 // Keep the controllers ticking after movement
112 RightMotionController->AddTickPrerequisiteComponent(GetCharacterMovement());
114 }
115
116 OffsetComponentToWorld = FTransform(FQuat(0.0f, 0.0f, 0.0f, 1.0f), FVector::ZeroVector, FVector(1.0f));
117
118
119 // Setting a minimum of every frame for replication consideration (UT uses this value for characters and projectiles).
120 // Otherwise we will get some massive slow downs if the replication is allowed to hit the 2 per second minimum default
121 MinNetUpdateFrequency = 100.0f;
122
123 // This is for smooth turning, we have more of a use for this than FPS characters do
124 // Due to roll/pitch almost never being off 0 for VR the cost is just one byte so i'm fine defaulting it here
125 // End users can reset to byte components if they ever want too.
126 MovementRep.RotationQuantizationLevel = ERotatorQuantization::ShortComponents;
127
129
131
133 bFlagTeleported = false;
134 bTrackingPaused = false;
135 PausedTrackingLoc = FVector::ZeroVector;
136 PausedTrackingRot = 0.f;
137}
138
139 void AVRBaseCharacter::PossessedBy(AController* NewController)
140 {
141 Super::PossessedBy(NewController);
142 OwningVRPlayerController = Cast<AVRPlayerController>(Controller);
143 }
144
146{
147 Super::OnRep_Controller();
148 OwningVRPlayerController = Cast<AVRPlayerController>(Controller);
149}
150
152{
153 OnPlayerStateReplicated_Bind.Broadcast(GetPlayerState());
154 Super::OnRep_PlayerState();
155}
156
158{
159 QUICK_SCOPE_CYCLE_COUNTER(STAT_Character_PostInitComponents);
160
161 Super::PostInitializeComponents();
162
163 if (!IsPendingKill())
164 {
165 if (NetSmoother)
166 {
167 CacheInitialMeshOffset(NetSmoother->GetRelativeLocation(), NetSmoother->GetRelativeRotation());
168 }
169
170 if (USkeletalMeshComponent * myMesh = GetMesh())
171 {
172 // force animation tick after movement component updates
173 if (myMesh->PrimaryComponentTick.bCanEverTick && GetMovementComponent())
174 {
175 myMesh->PrimaryComponentTick.AddPrerequisite(GetMovementComponent(), GetMovementComponent()->PrimaryComponentTick);
176 }
177 }
178
179 if (GetCharacterMovement() && GetCapsuleComponent())
180 {
181 GetCharacterMovement()->UpdateNavAgent(*GetCapsuleComponent());
182 }
183
184 if (Controller == nullptr && GetNetMode() != NM_Client)
185 {
186 if (GetCharacterMovement() && GetCharacterMovement()->bRunPhysicsWithNoController)
187 {
188 GetCharacterMovement()->SetDefaultMovementMode();
189 }
190 }
191 }
192}
193
194/*void AVRBaseCharacter::CacheInitialMeshOffset(FVector MeshRelativeLocation, FRotator MeshRelativeRotation)
195{
196 BaseTranslationOffset = MeshRelativeLocation;
197 BaseRotationOffset = MeshRelativeRotation.Quaternion();
198
199#if ENABLE_NAN_DIAGNOSTIC
200 if (BaseRotationOffset.ContainsNaN())
201 {
202 logOrEnsureNanError(TEXT("ACharacter::PostInitializeComponents detected NaN in BaseRotationOffset! (%s)"), *BaseRotationOffset.ToString());
203 }
204
205 if (GetMesh())
206 {
207 const FRotator LocalRotation = GetMesh()->GetRelativeRotation();
208 if (LocalRotation.ContainsNaN())
209 {
210 logOrEnsureNanError(TEXT("ACharacter::PostInitializeComponents detected NaN in Mesh->RelativeRotation! (%s)"), *LocalRotation.ToString());
211 }
212 }
213#endif
214}*/
215
216void AVRBaseCharacter::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty > & OutLifetimeProps) const
217{
218 Super::GetLifetimeReplicatedProps(OutLifetimeProps);
219 DOREPLIFETIME_CONDITION(AVRBaseCharacter, SeatInformation, COND_None);
220 DOREPLIFETIME_CONDITION(AVRBaseCharacter, VRReplicateCapsuleHeight, COND_None);
221 DOREPLIFETIME_CONDITION(AVRBaseCharacter, ReplicatedCapsuleHeight, COND_SimulatedOnly);
222
223 DISABLE_REPLICATED_PRIVATE_PROPERTY(AActor, ReplicatedMovement);
224
225 DOREPLIFETIME_CONDITION_NOTIFY(AVRBaseCharacter, ReplicatedMovementVR, COND_SimulatedOrPhysics, REPNOTIFY_Always);
226}
227
228void AVRBaseCharacter::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker)
229{
230 Super::PreReplication(ChangedPropertyTracker);
231
233 DOREPLIFETIME_ACTIVE_OVERRIDE(AVRBaseCharacter, ReplicatedMovementVR, IsReplicatingMovement());
234}
235
236/*USkeletalMeshComponent* AVRBaseCharacter::GetIKMesh_Implementation() const
237{
238 return GetMesh();
239// return nullptr;
240}*/
241
242bool AVRBaseCharacter::Server_SetSeatedMode_Validate(USceneComponent * SeatParent, bool bSetSeatedMode, FTransform_NetQuantize TargetTransform, FTransform_NetQuantize InitialRelCameraTransform, float AllowedRadius, float AllowedRadiusThreshold, bool bZeroToHead, EVRConjoinedMovementModes PostSeatedMovementMode)
243{
244 return true;
245}
246
247void AVRBaseCharacter::Server_SetSeatedMode_Implementation(USceneComponent * SeatParent, bool bSetSeatedMode, FTransform_NetQuantize TargetTransform, FTransform_NetQuantize InitialRelCameraTransform, float AllowedRadius, float AllowedRadiusThreshold, bool bZeroToHead, EVRConjoinedMovementModes PostSeatedMovementMode)
248{
249 SetSeatedMode(SeatParent, bSetSeatedMode, TargetTransform, InitialRelCameraTransform, AllowedRadius, AllowedRadiusThreshold, bZeroToHead, PostSeatedMovementMode);
250}
251
252void AVRBaseCharacter::Server_ReZeroSeating_Implementation(FTransform_NetQuantize NewTargetTransform, FTransform_NetQuantize NewInitialRelCameraTransform, bool bZeroToHead)
253{
254 SeatInformation.StoredTargetTransform = NewTargetTransform;
255 SeatInformation.InitialRelCameraTransform = NewInitialRelCameraTransform;
256
257 // Purify the yaw of the initial rotation
258 SeatInformation.InitialRelCameraTransform.SetRotation(UVRExpansionFunctionLibrary::GetHMDPureYaw_I(NewInitialRelCameraTransform.Rotator()).Quaternion());
259
260 // #TODO: Need to handle non 1 scaled values here eventually
261 if (bZeroToHead)
262 {
263 FVector newLocation = SeatInformation.InitialRelCameraTransform.GetTranslation();
264 SeatInformation.StoredTargetTransform.AddToTranslation(FVector(0, 0, -newLocation.Z));
265 }
266
268}
269
270bool AVRBaseCharacter::Server_ReZeroSeating_Validate(FTransform_NetQuantize NewTargetTransform, FTransform_NetQuantize NewInitialRelCameraTransform, bool bZeroToHead)
271{
272 return true;
273}
274
275void AVRBaseCharacter::OnCustomMoveActionPerformed_Implementation(EVRMoveAction MoveActionType, FVector MoveActionVector, FRotator MoveActionRotator, uint8 MoveActionFlags)
276{
277
278}
279
280void AVRBaseCharacter::OnBeginWallPushback_Implementation(FHitResult HitResultOfImpact, bool bHadLocomotionInput, FVector HmdInput)
281{
282
283}
284
289
294
295void AVRBaseCharacter::Server_SendTransformCamera_Implementation(FBPVRComponentPosRep NewTransform)
296{
298 VRReplicatedCamera->Server_SendCameraTransform_Implementation(NewTransform);
299}
300
301bool AVRBaseCharacter::Server_SendTransformCamera_Validate(FBPVRComponentPosRep NewTransform)
302{
303 return true;
304 // Optionally check to make sure that player is inside of their bounds and deny it if they aren't?
305}
306
307void AVRBaseCharacter::Server_SendTransformLeftController_Implementation(FBPVRComponentPosRep NewTransform)
308{
310 LeftMotionController->Server_SendControllerTransform_Implementation(NewTransform);
311}
312
313bool AVRBaseCharacter::Server_SendTransformLeftController_Validate(FBPVRComponentPosRep NewTransform)
314{
315 return true;
316 // Optionally check to make sure that player is inside of their bounds and deny it if they aren't?
317}
318
319void AVRBaseCharacter::Server_SendTransformRightController_Implementation(FBPVRComponentPosRep NewTransform)
320{
322 RightMotionController->Server_SendControllerTransform_Implementation(NewTransform);
323}
324
325bool AVRBaseCharacter::Server_SendTransformRightController_Validate(FBPVRComponentPosRep NewTransform)
326{
327 return true;
328 // Optionally check to make sure that player is inside of their bounds and deny it if they aren't?
329}
330FVector AVRBaseCharacter::GetTeleportLocation(FVector OriginalLocation)
331{
332 return OriginalLocation;
333}
334
335
336void AVRBaseCharacter::NotifyOfTeleport(bool bRegisterAsTeleport)
337{
338 if (bRegisterAsTeleport)
339 {
340 if (GetNetMode() < ENetMode::NM_Client)
341 bFlagTeleported = true;
342
344 {
346 }
347 }
348
349 if (GetNetMode() < ENetMode::NM_Client)
350 {
351 if (bRegisterAsTeleport)
352 {
353 bFlagTeleported = true;
354 }
355 else
356 {
358 }
359 }
360
363
366}
367
369{
370 FRepMovement& ReppedMovement = GetReplicatedMovement_Mutable();
371
372 ReppedMovement.AngularVelocity = ReplicatedMovementVR.AngularVelocity;
373 ReppedMovement.bRepPhysics = ReplicatedMovementVR.bRepPhysics;
374 ReppedMovement.bSimulatedPhysicSleep = ReplicatedMovementVR.bSimulatedPhysicSleep;
375 ReppedMovement.LinearVelocity = ReplicatedMovementVR.LinearVelocity;
376 ReppedMovement.Location = ReplicatedMovementVR.Location;
377 ReppedMovement.Rotation = ReplicatedMovementVR.Rotation;
378
379 Super::OnRep_ReplicatedMovement();
380
381 if (!IsLocallyControlled())
382 {
384 {
385 // Server should never get this value so it shouldn't be double throwing for them
387 }
389 {
390 NotifyOfTeleport(false);
391 }
392
394 if (bTrackingPaused)
395 {
398 }
399 }
400}
401
403{
404 Super::GatherCurrentMovement();
405
406 FRepMovement ReppedMovement = this->GetReplicatedMovement();
407
408 ReplicatedMovementVR.AngularVelocity = ReppedMovement.AngularVelocity;
409 ReplicatedMovementVR.bRepPhysics = ReppedMovement.bRepPhysics;
410 ReplicatedMovementVR.bSimulatedPhysicSleep = ReppedMovement.bSimulatedPhysicSleep;
411 ReplicatedMovementVR.LinearVelocity = ReppedMovement.LinearVelocity;
412 ReplicatedMovementVR.Location = ReppedMovement.Location;
413 ReplicatedMovementVR.Rotation = ReppedMovement.Rotation;
416 bFlagTeleported = false;
417 bFlagTeleportedGrips = false;
421}
422
423
425{
426 // Handle setting up the player here
427
428 if (UPrimitiveComponent * root = Cast<UPrimitiveComponent>(GetRootComponent()))
429 {
430 if (SeatInformation.bSitting /*&& !SeatInformation.bWasSeated*/) // Removing WasSeated check because we may be switching seats
431 {
433 {
434 if (SeatInformation.SeatParent != this->GetRootComponent()->GetAttachParent())
435 {
437 }
438 else // Is just a reposition
439 {
440 //if (this->Role != ROLE_SimulatedProxy)
442 }
443
444 }
445 else
446 {
447 if (this->GetLocalRole() == ROLE_SimulatedProxy)
448 {
449 /*if (UVRBaseCharacterMovementComponent * charMovement = Cast<UVRBaseCharacterMovementComponent>(GetMovementComponent()))
450 {
451 charMovement->SetMovementMode(MOVE_Custom, (uint8)EVRCustomMovementMode::VRMOVE_Seated);
452 }*/
453 }
454 else
455 {
457 {
458 VRMovementReference->SetMovementMode(MOVE_Custom, (uint8)EVRCustomMovementMode::VRMOVE_Seated);
459 }
460 }
461 }
462 }
464 {
465 if (this->GetLocalRole() == ROLE_SimulatedProxy)
466 {
467
468 /*if (UVRBaseCharacterMovementComponent * charMovement = Cast<UVRBaseCharacterMovementComponent>(GetMovementComponent()))
469 {
470 charMovement->ApplyReplicatedMovementMode(SeatInformation.PostSeatedMovementMode);
471 //charMovement->SetComponentTickEnabled(true);
472 }*/
473
474 }
475 else
476 {
478 {
480 }
481 }
482 }
483 }
484}
485
487{
488 if (UPrimitiveComponent * root = Cast<UPrimitiveComponent>(GetRootComponent()))
489 {
490 if (SeatInformation.bSitting /*&& !SeatInformation.bWasSeated*/) // Removing WasSeated check because we may be switching seats
491 {
492
493 if (SeatInformation.SeatParent /*&& !root->IsAttachedTo(SeatInformation.SeatParent)*/)
494 {
495 FAttachmentTransformRules TransformRule = FAttachmentTransformRules::SnapToTargetNotIncludingScale;
496 TransformRule.bWeldSimulatedBodies = true;
497 AttachToComponent(SeatInformation.SeatParent, TransformRule);
498 }
499
500 if (this->GetLocalRole() == ROLE_SimulatedProxy)
501 {
503 {
504 //charMovement->DisableMovement();
505 //charMovement->SetComponentTickEnabled(false);
506 //charMovement->SetMovementMode(MOVE_Custom, (uint8)EVRCustomMovementMode::VRMOVE_Seated);
507 }
508
509 root->SetCollisionEnabled(ECollisionEnabled::NoCollision);
510
511 // Set it before it is set below
513 SeatInformation.bOriginalControlRotation = bUseControllerRotationYaw;
514
516 bUseControllerRotationYaw = false; // This forces rotation in world space, something that we don't want
519 }
520 else
521 {
523 {
524 //charMovement->DisableMovement();
525 //charMovement->SetComponentTickEnabled(false);
526 //charMovement->SetMovementMode(MOVE_Custom, (uint8)EVRCustomMovementMode::VRMOVE_Seated);
527 //charMovement->bIgnoreClientMovementErrorChecksAndCorrection = true;
528
529 if (this->GetLocalRole() == ROLE_AutonomousProxy)
530 {
531 FNetworkPredictionData_Client_Character* ClientData = VRMovementReference->GetPredictionData_Client_Character();
532 check(ClientData);
533
534 if (ClientData->SavedMoves.Num())
535 {
536 // Ack our most recent move, we don't want to start sending old moves after un seating.
537 ClientData->AckMove(ClientData->SavedMoves.Num() - 1, *VRMovementReference);
538 }
539 }
540
541 }
542
543 root->SetCollisionEnabled(ECollisionEnabled::NoCollision);
544
545 // Set it before it is set below
547 {
548 SeatInformation.bOriginalControlRotation = bUseControllerRotationYaw;
549 }
550
552 bUseControllerRotationYaw = false; // This forces rotation in world space, something that we don't want
553
556 }
557 }
559 {
560 DetachFromActor(FDetachmentTransformRules::KeepWorldTransform);
561
562 if (this->GetLocalRole() == ROLE_SimulatedProxy)
563 {
564 root->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
565
566
567 bUseControllerRotationYaw = SeatInformation.bOriginalControlRotation;
568
570
572 {
574 }
575
577 {
579 }
580
581 /*if (UVRBaseCharacterMovementComponent * charMovement = Cast<UVRBaseCharacterMovementComponent>(GetMovementComponent()))
582 {
583 charMovement->ApplyReplicatedMovementMode(SeatInformation.PostSeatedMovementMode);
584 //charMovement->SetComponentTickEnabled(true);
585 }*/
586
588 }
589 else
590 {
592 {
593 //charMovement->ApplyReplicatedMovementMode(SeatInformation.PostSeatedMovementMode);
594 //charMovement->bIgnoreClientMovementErrorChecksAndCorrection = false;
595 //charMovement->SetComponentTickEnabled(true);
596
597 if (this->GetLocalRole() == ROLE_Authority)
598 {
600 {
602 FNetworkPredictionData_Server_Character * ServerData = VRMovementReference->GetPredictionData_Server_Character();
603 check(ServerData);
604 ServerData->CurrentClientTimeStamp = 0.0f;
605 ServerData->PendingAdjustment = FClientAdjustment();
606 //ServerData->CurrentClientTimeStamp = 0.f;
607 //ServerData->ServerAccumulatedClientTimeStamp = 0.0f;
608 //ServerData->LastUpdateTime = 0.f;
609 ServerData->ServerTimeStampLastServerMove = 0.f;
610 ServerData->bForceClientUpdate = false;
611 ServerData->TimeDiscrepancy = 0.f;
612 ServerData->bResolvingTimeDiscrepancy = false;
613 ServerData->TimeDiscrepancyResolutionMoveDeltaOverride = 0.f;
614 ServerData->TimeDiscrepancyAccumulatedClientDeltasSinceLastServerTick = 0.f;
615 }
616 //charMovement->ForceReplicationUpdate();
617 //FNetworkPredictionData_Server_Character * ServerData = charMovement->GetPredictionData_Server_Character();
618 //check(ServerData);
619
620 // Reset client timestamp check so that there isn't a delay on ending seated mode before we accept movement packets
621 //ServerData->CurrentClientTimeStamp = 1.f;
622 }
623 }
624
625 bUseControllerRotationYaw = SeatInformation.bOriginalControlRotation;
626
627 // Re-purposing them for the new location and rotations
631
632 // Enable collision now
633 root->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
634
637 }
638 }
639 }
640}
641
643{
644 float LastThresholdScaler = SeatInformation.CurrentThresholdScaler;
645 bool bLastOverThreshold = SeatInformation.bIsOverThreshold;
646
647 FVector NewLoc = VRReplicatedCamera->GetRelativeLocation();
648 FVector OrigLocation = SeatInformation.InitialRelCameraTransform.GetTranslation();
649
651 {
652 NewLoc.Z = 0.0f;
653 OrigLocation.Z = 0.0f;
654 }
655
656 if (FMath::IsNearlyZero(SeatInformation.AllowedRadius))
657 {
658 // Nothing to process here, seated mode isn't sticking to a set radius
660 {
662 bLastOverThreshold = false;
663 }
664 return;
665 }
666
667 float AbsDistance = FMath::Abs(FVector::Dist(OrigLocation, NewLoc));
668
669 //FTransform newTrans = SeatInformation.StoredTargetTransform * SeatInformation.SeatParent->GetComponentTransform();
670
671 // If over the allowed distance
672 if (AbsDistance > SeatInformation.AllowedRadius)
673 {
674 // Force them back into range
675 FVector diff = NewLoc - OrigLocation;
676 diff.Normalize();
677 diff = (-diff * (AbsDistance - SeatInformation.AllowedRadius));
678
681 }
682 else if (SeatInformation.bWasOverLimit) // Make sure we are in the zero point otherwise
683 {
684 SetSeatRelativeLocationAndRotationVR(FVector::ZeroVector);
686 }
687
690 else
692
694
695 if (bLastOverThreshold != SeatInformation.bIsOverThreshold || !FMath::IsNearlyEqual(LastThresholdScaler, SeatInformation.CurrentThresholdScaler))
696 {
699 }
700}
701
702bool AVRBaseCharacter::SetSeatedMode(USceneComponent * SeatParent, bool bSetSeatedMode, FTransform TargetTransform, FTransform InitialRelCameraTransform, float AllowedRadius, float AllowedRadiusThreshold, bool bZeroToHead, EVRConjoinedMovementModes PostSeatedMovementMode)
703{
704 if (!this->HasAuthority())
705 return false;
706
707 if (bSetSeatedMode)
708 {
709 if (!SeatParent)
710 return false;
711
712 SeatInformation.SeatParent = SeatParent;
714 SeatInformation.bZeroToHead = bZeroToHead;
715 SeatInformation.StoredTargetTransform = TargetTransform;
716 SeatInformation.InitialRelCameraTransform = InitialRelCameraTransform;
717
718 // Purify the yaw of the initial rotation
719 SeatInformation.InitialRelCameraTransform.SetRotation(UVRExpansionFunctionLibrary::GetHMDPureYaw_I(InitialRelCameraTransform.Rotator()).Quaternion());
720 SeatInformation.AllowedRadius = AllowedRadius;
721 SeatInformation.AllowedRadiusThreshold = AllowedRadiusThreshold;
722
723 // #TODO: Need to handle non 1 scaled values here eventually
724 if (bZeroToHead)
725 {
726 FVector newLocation = SeatInformation.InitialRelCameraTransform.GetTranslation();
727 SeatInformation.StoredTargetTransform.AddToTranslation(FVector(0, 0, -newLocation.Z));
728 }
729
730 //SetReplicateMovement(false);/ / No longer doing this, allowing it to replicate down to simulated clients now instead
731 }
732 else
733 {
734 SeatInformation.SeatParent = nullptr;
735 SeatInformation.StoredTargetTransform = TargetTransform;
736 SeatInformation.PostSeatedMovementMode = PostSeatedMovementMode;
737 //SetReplicateMovement(true); // No longer doing this, allowing it to replicate down to simulated clients now instead
739 }
740
741 OnRep_SeatedCharInfo(); // Call this on server side because it won't call itself
742 NotifyOfTeleport(); // Teleport the controllers
743
744 return true;
745}
746
748{
749 /*if (bUseYawOnly)
750 {
751 NewRot.Pitch = 0.0f;
752 NewRot.Roll = 0.0f;
753 }
754
755 NewLoc = NewLoc + Pivot;
756 NewLoc -= NewRot.RotateVector(Pivot);
757
758 SetActorRelativeTransform(FTransform(NewRot, NewLoc, GetCapsuleComponent()->RelativeScale3D));*/
759
760 FTransform NewTrans = SeatInformation.StoredTargetTransform;// *SeatInformation.SeatParent->GetComponentTransform();
761
762 FVector NewLocation;
763 FRotator NewRotation;
764 FVector PivotPoint = SeatInformation.InitialRelCameraTransform.GetTranslation();
765 PivotPoint.Z = 0.0f;
766
767 NewRotation = SeatInformation.InitialRelCameraTransform.Rotator();
768 NewRotation = (NewRotation.Quaternion().Inverse() * NewTrans.GetRotation()).Rotator();
769 NewLocation = NewTrans.GetTranslation();
770 NewLocation -= NewRotation.RotateVector(PivotPoint + (-DeltaLoc));
771
772 // Also setting actor rot because the control rot transfers to it anyway eventually
773 SetActorRelativeTransform(FTransform(NewRotation, NewLocation, GetCapsuleComponent()->GetRelativeScale3D()));
774}
775
776
777FVector AVRBaseCharacter::AddActorWorldRotationVR(FRotator DeltaRot, bool bUseYawOnly)
778{
779 AController* OwningController = GetController();
780
781 FVector NewLocation;
782 FRotator NewRotation;
783 FVector OrigLocation = GetActorLocation();
784 FVector PivotPoint = GetActorTransform().InverseTransformPosition(GetVRLocation_Inline());
785 PivotPoint.Z = 0.0f;
786
787 NewRotation = bUseControllerRotationYaw && OwningController ? OwningController->GetControlRotation() : GetActorRotation();
788
789 if (bUseYawOnly)
790 {
791 NewRotation.Pitch = 0.0f;
792 NewRotation.Roll = 0.0f;
793 }
794
795 NewLocation = OrigLocation + NewRotation.RotateVector(PivotPoint);
796 NewRotation = (NewRotation.Quaternion() * DeltaRot.Quaternion()).Rotator();
797 NewLocation -= NewRotation.RotateVector(PivotPoint);
798
799 if (bUseControllerRotationYaw && OwningController /*&& IsLocallyControlled()*/)
800 OwningController->SetControlRotation(NewRotation);
801
802 // Also setting actor rot because the control rot transfers to it anyway eventually
803 SetActorLocationAndRotation(NewLocation, NewRotation);
804 return NewLocation - OrigLocation;
805}
806
807FVector AVRBaseCharacter::SetActorRotationVR(FRotator NewRot, bool bUseYawOnly, bool bAccountForHMDRotation)
808{
809 AController* OwningController = GetController();
810
811 FVector NewLocation;
812 FRotator NewRotation;
813 FVector OrigLocation = GetActorLocation();
814 FVector PivotPoint = GetActorTransform().InverseTransformPosition(GetVRLocation_Inline());
815 PivotPoint.Z = 0.0f;
816
817 FRotator OrigRotation = bUseControllerRotationYaw && OwningController ? OwningController->GetControlRotation() : GetActorRotation();
818
819 if (bUseYawOnly)
820 {
821 NewRot.Pitch = 0.0f;
822 NewRot.Roll = 0.0f;
823 }
824
825 if (bAccountForHMDRotation)
826 {
827 NewRotation = UVRExpansionFunctionLibrary::GetHMDPureYaw_I(VRReplicatedCamera->GetRelativeRotation());
828 NewRotation = (NewRot.Quaternion() * NewRotation.Quaternion().Inverse()).Rotator();
829 }
830 else
831 NewRotation = NewRot;
832
833 NewLocation = OrigLocation + OrigRotation.RotateVector(PivotPoint);
834 //NewRotation = NewRot;
835 NewLocation -= NewRotation.RotateVector(PivotPoint);
836
837 if (bUseControllerRotationYaw && OwningController /*&& IsLocallyControlled()*/)
838 OwningController->SetControlRotation(NewRotation);
839
840 // Also setting actor rot because the control rot transfers to it anyway eventually
841 SetActorLocationAndRotation(NewLocation, NewRotation);
842 return NewLocation - OrigLocation;
843}
844
845FVector AVRBaseCharacter::SetActorLocationAndRotationVR(FVector NewLoc, FRotator NewRot, bool bUseYawOnly, bool bAccountForHMDRotation, bool bTeleport)
846{
847 AController* OwningController = GetController();
848
849 FVector NewLocation;
850 FRotator NewRotation;
851 FVector PivotPoint = GetActorTransform().InverseTransformPosition(GetVRLocation_Inline());
852 PivotPoint.Z = 0.0f;
853
854 if (bUseYawOnly)
855 {
856 NewRot.Pitch = 0.0f;
857 NewRot.Roll = 0.0f;
858 }
859
860 if (bAccountForHMDRotation)
861 {
862 NewRotation = UVRExpansionFunctionLibrary::GetHMDPureYaw_I(VRReplicatedCamera->GetRelativeRotation());//bUseControllerRotationYaw && OwningController ? OwningController->GetControlRotation() : GetActorRotation();
863 NewRotation = (NewRot.Quaternion() * NewRotation.Quaternion().Inverse()).Rotator();
864 }
865 else
866 NewRotation = NewRot;
867
868 NewLocation = NewLoc;// +PivotPoint;// NewRotation.RotateVector(PivotPoint);
869 //NewRotation = NewRot;
870 NewLocation -= NewRotation.RotateVector(PivotPoint);
871
872 if (bUseControllerRotationYaw && OwningController /*&& IsLocallyControlled()*/)
873 OwningController->SetControlRotation(NewRotation);
874
875 // Also setting actor rot because the control rot transfers to it anyway eventually
876 SetActorLocationAndRotation(NewLocation, NewRotation, false, nullptr, bTeleport ? ETeleportType::TeleportPhysics : ETeleportType::None);
877 return NewLocation - NewLoc;
878}
879
880FVector AVRBaseCharacter::SetActorLocationVR(FVector NewLoc, bool bTeleport)
881{
882 FVector NewLocation;
883 FRotator NewRotation;
884 FVector PivotOffsetVal = GetVRLocation_Inline() - GetActorLocation();
885 PivotOffsetVal.Z = 0.0f;
886
887
888 NewLocation = NewLoc - PivotOffsetVal;// +PivotPoint;// NewRotation.RotateVector(PivotPoint);
889 //NewRotation = NewRot;
890
891
892 // Also setting actor rot because the control rot transfers to it anyway eventually
893 SetActorLocation(NewLocation, false, nullptr, bTeleport ? ETeleportType::TeleportPhysics : ETeleportType::None);
894 return NewLocation - NewLoc;
895}
896
897
898void AVRBaseCharacter::SetCharacterSizeVR(float NewRadius, float NewHalfHeight, bool bUpdateOverlaps)
899{
900 if (UCapsuleComponent * Capsule = Cast<UCapsuleComponent>(this->RootComponent))
901 {
902 if (!FMath::IsNearlyEqual(NewRadius, Capsule->GetUnscaledCapsuleRadius()) || !FMath::IsNearlyEqual(NewHalfHeight, Capsule->GetUnscaledCapsuleHalfHeight()))
903 Capsule->SetCapsuleSize(NewRadius, NewHalfHeight, bUpdateOverlaps);
904
905 if (GetNetMode() < ENetMode::NM_Client && VRReplicateCapsuleHeight)
906 ReplicatedCapsuleHeight.CapsuleHeight = Capsule->GetUnscaledCapsuleHalfHeight();
907 }
908}
909
910void AVRBaseCharacter::SetCharacterHalfHeightVR(float HalfHeight, bool bUpdateOverlaps)
911{
912 if (UCapsuleComponent * Capsule = Cast<UCapsuleComponent>(this->RootComponent))
913 {
914 if (!FMath::IsNearlyEqual(HalfHeight, Capsule->GetUnscaledCapsuleHalfHeight()))
915 Capsule->SetCapsuleHalfHeight(HalfHeight, bUpdateOverlaps);
916
917 if (GetNetMode() < ENetMode::NM_Client && VRReplicateCapsuleHeight)
918 ReplicatedCapsuleHeight.CapsuleHeight = Capsule->GetUnscaledCapsuleHalfHeight();
919 }
920}
921
922void AVRBaseCharacter::ExtendedSimpleMoveToLocation(const FVector& GoalLocation, float AcceptanceRadius, bool bStopOnOverlap, bool bUsePathfinding, bool bProjectDestinationToNavigation, bool bCanStrafe, TSubclassOf<UNavigationQueryFilter> FilterClass, bool bAllowPartialPaths)
923{
924 UNavigationSystemV1* NavSys = Controller ? FNavigationSystem::GetCurrent<UNavigationSystemV1>(Controller->GetWorld()) : nullptr;
925 if (NavSys == nullptr || Controller == nullptr )
926 {
927 UE_LOG(LogBaseVRCharacter, Warning, TEXT("UVRSimpleCharacter::ExtendedSimpleMoveToLocation called for NavSys:%s Controller:%s (if any of these is None then there's your problem"),
928 *GetNameSafe(NavSys), *GetNameSafe(Controller));
929 return;
930 }
931
932 UPathFollowingComponent* PFollowComp = nullptr;
933 //Controller->InitNavigationControl(PFollowComp);
934 if (Controller)
935 {
936 // New for 4.20, spawning the missing path following component here if there isn't already one
937 PFollowComp = Controller->FindComponentByClass<UPathFollowingComponent>();
938 if (PFollowComp == nullptr)
939 {
940 PFollowComp = NewObject<UVRPathFollowingComponent>(Controller);
941 PFollowComp->RegisterComponentWithWorld(Controller->GetWorld());
942 PFollowComp->Initialize();
943 }
944 }
945
946 if (PFollowComp == nullptr)
947 {
948 UE_LOG(LogBaseVRCharacter, Warning, TEXT("ExtendedSimpleMoveToLocation - No PathFollowingComponent Found"));
949 return;
950 }
951
952 if (!PFollowComp->IsPathFollowingAllowed())
953 {
954 UE_LOG(LogBaseVRCharacter, Warning, TEXT("ExtendedSimpleMoveToLocation - Path Following Movement Is Not Set To Allowed"));
955 return;
956 }
957
958 EPathFollowingReachMode ReachMode;
959 if (bStopOnOverlap)
960 ReachMode = EPathFollowingReachMode::OverlapAgent;
961 else
962 ReachMode = EPathFollowingReachMode::ExactLocation;
963
964 bool bAlreadyAtGoal = false;
965
966 if(UVRPathFollowingComponent * pathcomp = Cast<UVRPathFollowingComponent>(PFollowComp))
967 bAlreadyAtGoal = pathcomp->HasReached(GoalLocation, /*EPathFollowingReachMode::OverlapAgent*/ReachMode);
968 else
969 bAlreadyAtGoal = PFollowComp->HasReached(GoalLocation, /*EPathFollowingReachMode::OverlapAgent*/ReachMode);
970
971 // script source, keep only one move request at time
972 if (PFollowComp->GetStatus() != EPathFollowingStatus::Idle)
973 {
974 if (GetNetMode() == ENetMode::NM_Client)
975 {
976 // Stop the movement here, not keeping the velocity because it bugs out for clients, might be able to fix.
977 PFollowComp->AbortMove(*NavSys, FPathFollowingResultFlags::ForcedScript | FPathFollowingResultFlags::NewRequest
978 , FAIRequestID::AnyRequest, /*bAlreadyAtGoal ? */EPathFollowingVelocityMode::Reset /*: EPathFollowingVelocityMode::Keep*/);
979 }
980 else
981 {
982 PFollowComp->AbortMove(*NavSys, FPathFollowingResultFlags::ForcedScript | FPathFollowingResultFlags::NewRequest
983 , FAIRequestID::AnyRequest, bAlreadyAtGoal ? EPathFollowingVelocityMode::Reset : EPathFollowingVelocityMode::Keep);
984 }
985 }
986
987 if (bAlreadyAtGoal)
988 {
989 PFollowComp->RequestMoveWithImmediateFinish(EPathFollowingResult::Success);
990 }
991 else
992 {
993 const ANavigationData* NavData = NavSys->GetNavDataForProps(Controller->GetNavAgentPropertiesRef());
994 if (NavData)
995 {
996 FPathFindingQuery Query(Controller, *NavData, Controller->GetNavAgentLocation(), GoalLocation);
997 FPathFindingResult Result = NavSys->FindPathSync(Query);
998 if (Result.IsSuccessful())
999 {
1000 FAIMoveRequest MoveReq(GoalLocation);
1001 MoveReq.SetUsePathfinding(bUsePathfinding);
1002 MoveReq.SetAllowPartialPath(bAllowPartialPaths);
1003 MoveReq.SetProjectGoalLocation(bProjectDestinationToNavigation);
1004 MoveReq.SetNavigationFilter(*FilterClass ? FilterClass : DefaultNavigationFilterClass);
1005 MoveReq.SetAcceptanceRadius(AcceptanceRadius);
1006 MoveReq.SetReachTestIncludesAgentRadius(bStopOnOverlap);
1007 MoveReq.SetCanStrafe(bCanStrafe);
1008 MoveReq.SetReachTestIncludesGoalRadius(true);
1009
1010 PFollowComp->RequestMove(/*FAIMoveRequest(GoalLocation)*/MoveReq, Result.Path);
1011 }
1012 else if (PFollowComp->GetStatus() != EPathFollowingStatus::Idle)
1013 {
1014 PFollowComp->RequestMoveWithImmediateFinish(EPathFollowingResult::Invalid);
1015 }
1016 }
1017 }
1018}
1019
1020bool AVRBaseCharacter::GetCurrentNavigationPathPoints(TArray<FVector>& NavigationPointList)
1021{
1022 UPathFollowingComponent* PFollowComp = nullptr;
1023 if (Controller)
1024 {
1025 // New for 4.20, spawning the missing path following component here if there isn't already one
1026 PFollowComp = Controller->FindComponentByClass<UPathFollowingComponent>();
1027 if (PFollowComp)
1028 {
1029 FNavPathSharedPtr NavPtr = PFollowComp->GetPath();
1030 if (NavPtr.IsValid())
1031 {
1032 TArray<FNavPathPoint>& NavPoints = NavPtr->GetPathPoints();
1033 if (NavPoints.Num())
1034 {
1035 FTransform BaseTransform = FTransform::Identity;
1036 if (AActor* BaseActor = NavPtr->GetBaseActor())
1037 {
1038 BaseTransform = BaseActor->GetActorTransform();
1039 }
1040
1041 NavigationPointList.Empty(NavPoints.Num());
1042 NavigationPointList.AddUninitialized(NavPoints.Num());
1043
1044 int counter = 0;
1045 for (FNavPathPoint& pt : NavPoints)
1046 {
1047 NavigationPointList[counter++] = BaseTransform.TransformPosition(pt.Location);
1048 }
1049
1050 return true;
1051 }
1052 }
1053
1054 return false;
1055 }
1056 }
1057
1058 return false;
1059}
EVRMoveAction
UENUM(Blueprintable)
EVRConjoinedMovementModes
UENUM(BlueprintType)
DEFINE_LOG_CATEGORY(LogBaseVRCharacter)
FVRSeatedCharacterInfo SeatInformation
UPROPERTY(BlueprintReadOnly, Replicated, EditAnywhere, Category = "Seating", ReplicatedUsing = OnRep_...
USceneComponent * VRProxyComponent
UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess ...
bool SetSeatedMode(USceneComponent *SeatParent, bool bSetSeatedMode, FTransform TargetTransform, FTransform InitialRelCameraTransform, float AllowedRadius=40.0f, float AllowedRadiusThreshold=20.0f, bool bZeroToHead=true, EVRConjoinedMovementModes PostSeatedMovementMode=EVRConjoinedMovementModes::C_MOVE_Walking)
FVRReplicatedCapsuleHeight ReplicatedCapsuleHeight
UPROPERTY(Replicated, ReplicatedUsing = OnRep_CapsuleHeight)
FVRSeatThresholdChangedSignature OnSeatThreshholdChanged_Bind
UPROPERTY(BlueprintAssignable, Category = "Seating")
static FName ReplicatedCameraComponentName
virtual void SetCharacterSizeVR(float NewRadius, float NewHalfHeight, bool bUpdateOverlaps=true)
UFUNCTION(BlueprintCallable, Category = "BaseVRCharacter")
void OnSeatedModeChanged(bool bNewSeatedMode, bool bWasAlreadySeated)
UFUNCTION(BlueprintNativeEvent, Category = "Seating")
virtual void OnRep_SeatedCharInfo()
UFUNCTION()
virtual void GatherCurrentMovement() override
virtual void OnEndWallPushback_Implementation()
USceneComponent * NetSmoother
UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess ...
FVector SetActorRotationVR(FRotator NewRot, bool bUseYawOnly=true, bool bAccountForHMDRotation=true)
UFUNCTION(BlueprintCallable, Category = "BaseVRCharacter|VRLocations")
UGripMotionControllerComponent * RightMotionController
UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess ...
FVector SetActorLocationVR(FVector NewLoc, bool bTeleport)
UFUNCTION(BlueprintCallable, Category = "BaseVRCharacter|VRLocations")
virtual void PreReplication(IRepChangedPropertyTracker &ChangedPropertyTracker) override
virtual FVector GetTeleportLocation(FVector OriginalLocation)
UFUNCTION(BlueprintPure, Category = "VRGrip")
static FName LeftMotionControllerComponentName
struct FRepMovementVRCharacter ReplicatedMovementVR
UPROPERTY(ReplicatedUsing = OnRep_ReplicatedMovement)
void Server_SendTransformRightController(FBPVRComponentPosRep NewTransform)
UFUNCTION(Unreliable, Server, WithValidation)
virtual void OnBeginWallPushback_Implementation(FHitResult HitResultOfImpact, bool bHadLocomotionInput, FVector HmdInput)
FVector AddActorWorldRotationVR(FRotator DeltaRot, bool bUseYawOnly=true)
UFUNCTION(BlueprintCallable, Category = "BaseVRCharacter|VRLocations")
virtual void OnRep_PlayerState() override
FVector SetActorLocationAndRotationVR(FVector NewLoc, FRotator NewRot, bool bUseYawOnly=true, bool bAccountForHMDRotation=true, bool bTeleport=false)
UFUNCTION(BlueprintCallable, Category = "BaseVRCharacter|VRLocations")
AVRBaseCharacter(const FObjectInitializer &ObjectInitializer=FObjectInitializer::Get())
virtual void OnClimbingSteppedUp_Implementation()
static FName VRProxyComponentName
virtual void ExtendedSimpleMoveToLocation(const FVector &GoalLocation, float AcceptanceRadius=-1, bool bStopOnOverlap=false, bool bUsePathfinding=true, bool bProjectDestinationToNavigation=true, bool bCanStrafe=false, TSubclassOf< UNavigationQueryFilter > FilterClass=NULL, bool bAllowPartialPath=true)
UFUNCTION(BlueprintCallable, Category = "VRBaseCharacter|Navigation", Meta = (AdvancedDisplay = "bSto...
static FName SmoothingSceneParentComponentName
FTransform OffsetComponentToWorld
UPROPERTY(BlueprintReadOnly, Transient, Category = "VRExpansionLibrary")
static FName RightMotionControllerComponentName
void TickSeatInformation(float DeltaTime)
FVRPlayerStateReplicatedSignature OnPlayerStateReplicated_Bind
UPROPERTY(BlueprintAssignable, Category = "VRMovement")
bool VRReplicateCapsuleHeight
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRBaseCharacter")
virtual void OnRep_Controller() override
static FName ParentRelativeAttachmentComponentName
virtual void PostInitializeComponents() override
bool GetCurrentNavigationPathPoints(TArray< FVector > &NavigationPointList)
UFUNCTION(BlueprintCallable, Category = "VRBaseCharacter|Navigation")
void SetSeatRelativeLocationAndRotationVR(FVector LocDelta)
virtual void OnCustomMoveActionPerformed_Implementation(EVRMoveAction MoveActionType, FVector MoveActionVector, FRotator MoveActionRotator, uint8 MoveActionFlags)
virtual void PossessedBy(AController *NewController)
UVRBaseCharacterMovementComponent * VRMovementReference
UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, Transient, BlueprintReadOnly,...
UReplicatedVRCameraComponent * VRReplicatedCamera
UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess ...
virtual void NotifyOfTeleport(bool bRegisterAsTeleport=true)
UFUNCTION(BlueprintCallable, Category = "VRGrip")
TSubclassOf< UNavigationQueryFilter > DefaultNavigationFilterClass
UPROPERTY(BlueprintReadWrite, Category = AI)
UGripMotionControllerComponent * LeftMotionController
UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess ...
void OnSeatThreshholdChanged(bool bIsWithinThreshold, float ToThresholdScaler)
UFUNCTION(BlueprintNativeEvent, Category = "Seating")
bool bUseExperimentalUnseatModeFix
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRBaseCharacter")
virtual void SetCharacterHalfHeightVR(float HalfHeight, bool bUpdateOverlaps=true)
UFUNCTION(BlueprintCallable, Category = "BaseVRCharacter")
UParentRelativeAttachmentComponent * ParentRelativeAttachment
UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess ...
void Server_SendTransformLeftController(FBPVRComponentPosRep NewTransform)
UFUNCTION(Unreliable, Server, WithValidation)
virtual void OnRep_ReplicatedMovement() override
AVRPlayerController * OwningVRPlayerController
UPROPERTY(Transient, DuplicateTransient)
FVector GetVRLocation_Inline() const
void Server_SendTransformCamera(FBPVRComponentPosRep NewTransform)
UFUNCTION(Unreliable, Server, WithValidation)
void PostTeleportMoveGrippedObjects()
UFUNCTION(BlueprintCallable, Category = "GripMotionController")
bool bOffsetByHMD
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripMotionController|Advanced|Tracking")
VRBaseCharTransformRPC_Pointer OverrideSendTransform
bool bOffsetByHMD
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRExpansionLibrary")
bool bOffsetByHMD
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ReplicatedCamera")
VRBaseCharTransformRPC_Pointer OverrideSendTransform
FORCEINLINE void ApplyReplicatedMovementMode(EVRConjoinedMovementModes &NewMovementMode, bool bClearMovementMode=false)
static FRotator GetHMDPureYaw_I(FRotator HMDRotation)
bool bJustTeleported
UPROPERTY(Transient)
bool bJustTeleportedGrips
UPROPERTY(Transient)
AActor * Owner
UPROPERTY(Transient)
FVector_NetQuantize100 PausedTrackingLoc
UPROPERTY(Transient)
bool bPausedTracking
UPROPERTY(Transient)
float PausedTrackingRot
UPROPERTY(Transient)
USTRUCT(BlueprintType, Category = "VRExpansionLibrary|TransformNetQuantize", meta = (HasNativeMake = ...
FTransform_NetQuantize StoredTargetTransform
UPROPERTY(BlueprintReadOnly, Category = "CharacterSeatInfo")
float AllowedRadius
UPROPERTY(EditAnywhere, BlueprintReadWrite, NotReplicated, Category = "CharacterSeatInfo",...
bool bIsOverThreshold
UPROPERTY(BlueprintReadOnly, NotReplicated, Category = "CharacterSeatInfo")
EVRConjoinedMovementModes PostSeatedMovementMode
UPROPERTY(BlueprintReadOnly, Category = "CharacterSeatInfo")
FTransform_NetQuantize InitialRelCameraTransform
UPROPERTY(BlueprintReadOnly, Category = "CharacterSeatInfo")
float CurrentThresholdScaler
UPROPERTY(BlueprintReadOnly, NotReplicated, Category = "CharacterSeatInfo")
USceneComponent * SeatParent
UPROPERTY(BlueprintReadOnly, Category = "CharacterSeatInfo")
bool bZeroToHead
UPROPERTY(BlueprintReadOnly, Category = "CharacterSeatInfo")
bool bSitting
UPROPERTY(BlueprintReadOnly, Category = "CharacterSeatInfo")
float AllowedRadiusThreshold
UPROPERTY(EditAnywhere, BlueprintReadWrite, NotReplicated, Category = "CharacterSeatInfo",...