A Demo Project for the UnrealEngineSDK
Loading...
Searching...
No Matches
VRBaseCharacter.h
Go to the documentation of this file.
1// Fill out your copyright notice in the Description page of Project Settings.
2
3#pragma once
4#include "CoreMinimal.h"
5#include "VRBPDatatypes.h"
6#include "Navigation/PathFollowingComponent.h"
11#include "GameFramework/Character.h"
12#include "GameFramework/Controller.h"
13#include "Components/CapsuleComponent.h"
14#include "VRBaseCharacter.generated.h"
15
17
18DECLARE_LOG_CATEGORY_EXTERN(LogBaseVRCharacter, Log, All);
19
21DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FVRSeatThresholdChangedSignature, bool, bIsWithinThreshold, float, ToThresholdScaler);
22DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FVRPlayerStateReplicatedSignature, const APlayerState *, NewPlayerState);
23DECLARE_DYNAMIC_MULTICAST_DELEGATE(FVRPlayerTeleportedSignature);
24DECLARE_DYNAMIC_MULTICAST_DELEGATE(FVRPlayerNetworkCorrectedSignature);
25
26USTRUCT()
27struct VREXPANSIONPLUGIN_API FRepMovementVRCharacter : public FRepMovement
28{
30
31public:
32
34
35 UPROPERTY(Transient)
36 bool bJustTeleported;
37
38 UPROPERTY(Transient)
39 bool bJustTeleportedGrips;
40
41 UPROPERTY(Transient)
42 bool bPausedTracking;
43
44 UPROPERTY(Transient)
45 FVector_NetQuantize100 PausedTrackingLoc;
46
47 UPROPERTY(Transient)
48 float PausedTrackingRot;
49
50 UPROPERTY(Transient)
51 AActor* Owner;
52
53 bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess)
54 {
55 FRepMovement BaseSettings = Owner ? Owner->GetReplicatedMovement() : FRepMovement();
56
57 // pack bitfield with flags
58 uint8 Flags = (bSimulatedPhysicSleep << 0) | (bRepPhysics << 1) | (bJustTeleported << 2) | (bJustTeleportedGrips << 3) | (bPausedTracking << 4);
59 Ar.SerializeBits(&Flags, 5);
60 bSimulatedPhysicSleep = (Flags & (1 << 0)) ? 1 : 0;
61 bRepPhysics = (Flags & (1 << 1)) ? 1 : 0;
62 bJustTeleported = (Flags & (1 << 2)) ? 1 : 0;
63 bJustTeleportedGrips = (Flags & (1 << 3)) ? 1 : 0;
64 bPausedTracking = (Flags & (1 << 4)) ? 1 : 0;
66 bOutSuccess = true;
67
68 if (bPausedTracking)
69 {
70 bOutSuccess &= PausedTrackingLoc.NetSerialize(Ar, Map, bOutSuccess);
72 uint16 Yaw = 0;
73 if (Ar.IsSaving())
74 {
75 Yaw = FRotator::CompressAxisToShort(PausedTrackingRot);
76 Ar << Yaw;
77 }
78 else
79 {
80 Ar << Yaw;
81 PausedTrackingRot = Yaw;
82 }
83
84 }
85
86 // update location, rotation, linear velocity
87 bOutSuccess &= SerializeQuantizedVector(Ar, Location, BaseSettings.LocationQuantizationLevel);
88
89 switch (BaseSettings.RotationQuantizationLevel)
90 {
91 case ERotatorQuantization::ByteComponents:
92 {
93 Rotation.SerializeCompressed(Ar);
94 break;
95 }
96
97 case ERotatorQuantization::ShortComponents:
98 {
99 Rotation.SerializeCompressedShort(Ar);
100 break;
101 }
102 }
103
104 bOutSuccess &= SerializeQuantizedVector(Ar, LinearVelocity, BaseSettings.VelocityQuantizationLevel);
105
106 // update angular velocity if required
107 if (bRepPhysics)
108 {
109 bOutSuccess &= SerializeQuantizedVector(Ar, AngularVelocity, BaseSettings.VelocityQuantizationLevel);
110 }
111
112 return true;
113 }
114};
115
116template<>
117struct TStructOpsTypeTraits<FRepMovementVRCharacter> : public TStructOpsTypeTraitsBase2<FRepMovementVRCharacter>
118{
119 enum
120 {
121 WithNetSerializer = true,
122 WithNetSharedSerialization = true,
123 };
124};
125
126USTRUCT(Blueprintable)
127struct VREXPANSIONPLUGIN_API FVRSeatedCharacterInfo
128{
129 GENERATED_USTRUCT_BODY()
130public:
131 UPROPERTY(BlueprintReadOnly, Category = "CharacterSeatInfo")
132 bool bSitting;
133 UPROPERTY(BlueprintReadOnly, Category = "CharacterSeatInfo")
134 bool bZeroToHead;
135 UPROPERTY(BlueprintReadOnly, Category = "CharacterSeatInfo")
136 FTransform_NetQuantize StoredTargetTransform;
137 UPROPERTY(BlueprintReadOnly, Category = "CharacterSeatInfo")
138 FTransform_NetQuantize InitialRelCameraTransform;
139 UPROPERTY(BlueprintReadOnly, Category = "CharacterSeatInfo")
140 USceneComponent* SeatParent;
141 UPROPERTY(BlueprintReadOnly, Category = "CharacterSeatInfo")
142 EVRConjoinedMovementModes PostSeatedMovementMode;
143
144 UPROPERTY(EditAnywhere, BlueprintReadWrite, NotReplicated, Category = "CharacterSeatInfo", meta = (ClampMin = "1.000", UIMin = "1.000", ClampMax = "256.000", UIMax = "256.000"))
145 float AllowedRadius;
146 UPROPERTY(EditAnywhere, BlueprintReadWrite, NotReplicated, Category = "CharacterSeatInfo", meta = (ClampMin = "1.000", UIMin = "1.000", ClampMax = "256.000", UIMax = "256.000"))
147 float AllowedRadiusThreshold;
148 UPROPERTY(BlueprintReadOnly, NotReplicated, Category = "CharacterSeatInfo")
149 float CurrentThresholdScaler;
150 UPROPERTY(BlueprintReadOnly, NotReplicated, Category = "CharacterSeatInfo")
151 bool bIsOverThreshold;
153 bool bWasSeated;
154 bool bOriginalControlRotation;
155 bool bWasOverLimit;
156
159 Clear();
160 }
161
162 void Clear()
164 bSitting = false;
165 bIsOverThreshold = false;
166 bWasOverLimit = false;
167 bZeroToHead = true;
168 StoredTargetTransform = FTransform::Identity;
169 InitialRelCameraTransform = FTransform::Identity;
170 bWasSeated = false;
171 bOriginalControlRotation = false;
172 AllowedRadius = 40.0f;
173 AllowedRadiusThreshold = 20.0f;
174 CurrentThresholdScaler = 0.0f;
175 SeatParent = nullptr;
176 PostSeatedMovementMode = EVRConjoinedMovementModes::C_MOVE_Walking;
177 }
179 void ClearTempVals()
180 {
181 bWasOverLimit = false;
182 bWasSeated = false;
183 bOriginalControlRotation = false;
184 CurrentThresholdScaler = 0.0f;
185 }
186
187
189 // Doing a custom NetSerialize here because this is sent via RPCs and should change on every update
190 bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess)
192 bOutSuccess = true;
193
194 Ar.SerializeBits(&bSitting, 1);
195 Ar.SerializeBits(&bZeroToHead, 1);
196
197 if (bSitting)
199 InitialRelCameraTransform.NetSerialize(Ar, Map, bOutSuccess);
200
201 // Forcing a maximum value here so that we can compress it by making assumptions
202 // 256 max value = 8 bits + 1 bit for sign + 7 bits for precision (up to 128 on precision, so full range 2 digit precision).
203 if (Ar.IsSaving())
205 bOutSuccess &= WriteFixedCompressedFloat<256, 16>(AllowedRadius, Ar);
206 bOutSuccess &= WriteFixedCompressedFloat<256, 16>(AllowedRadiusThreshold, Ar);
207 }
208 else
209 {
210 bOutSuccess &= ReadFixedCompressedFloat<256, 16>(AllowedRadius, Ar);
211 bOutSuccess &= ReadFixedCompressedFloat<256, 16>(AllowedRadiusThreshold, Ar);
215 StoredTargetTransform.NetSerialize(Ar, Map, bOutSuccess);
216 Ar << SeatParent;
217 Ar << PostSeatedMovementMode;
218 return bOutSuccess;
219 }
220};
221template<>
222struct TStructOpsTypeTraits< FVRSeatedCharacterInfo > : public TStructOpsTypeTraitsBase2<FVRSeatedCharacterInfo>
223{
224 enum
225 {
226 WithNetSerializer = true
227 };
228};
229
230USTRUCT()
231struct VREXPANSIONPLUGIN_API FVRReplicatedCapsuleHeight
232{
233 GENERATED_USTRUCT_BODY()
234public:
235 UPROPERTY()
236 float CapsuleHeight;
237
239 CapsuleHeight(0.0f)
240 {}
241
243 bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess)
244 {
245 bOutSuccess = true;
246 // Forcing a maximum value here so that we can compress it by making assumptions
247 // 1024 max value = 10 bits + 1 bit for sign + 7 bits for precision (up to 128 on precision, so full range 2 digit precision).
248 if (Ar.IsSaving())
250 bOutSuccess &= WriteFixedCompressedFloat<1024, 18>(CapsuleHeight, Ar);
251 }
252 else
253 {
254 bOutSuccess &= ReadFixedCompressedFloat<1024, 18>(CapsuleHeight, Ar);
255 }
256
257 return bOutSuccess;
258 }
259};
260template<>
261struct TStructOpsTypeTraits< FVRReplicatedCapsuleHeight > : public TStructOpsTypeTraitsBase2<FVRReplicatedCapsuleHeight>
262{
263 enum
264 {
265 WithNetSerializer = true
266 };
267};
268
269UCLASS()
270class VREXPANSIONPLUGIN_API AVRBaseCharacter : public ACharacter
271{
272 GENERATED_BODY()
273
274public:
275 AVRBaseCharacter(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());
276
278 UPROPERTY(Transient, DuplicateTransient)
279 AVRPlayerController* OwningVRPlayerController;
280
281 //virtual void CacheInitialMeshOffset(FVector MeshRelativeLocation, FRotator MeshRelativeRotation) override;
282 virtual void PostInitializeComponents() override;
283
284 virtual void PossessedBy(AController* NewController);
285 virtual void OnRep_Controller() override;
286 virtual void OnRep_PlayerState() override;
287
289 UPROPERTY(ReplicatedUsing = OnRep_ReplicatedMovement)
290 struct FRepMovementVRCharacter ReplicatedMovementVR;
291
292 bool bFlagTeleported;
293 bool bFlagTeleportedGrips;
294 bool bTrackingPaused;
295 FVector PausedTrackingLoc;
296 float PausedTrackingRot;
297
298 // Injecting our custom teleport notification
299 virtual void OnRep_ReplicatedMovement() override;
300 virtual void GatherCurrentMovement() override;
302 // Give my users direct access to an event for when the player has teleported
303 UPROPERTY(BlueprintAssignable, Category = "VRMovement")
304 FVRPlayerTeleportedSignature OnCharacterTeleported_Bind;
305
306 // Give my users direct access to an event for when the player has been network corrected
307 UPROPERTY(BlueprintAssignable, Category = "VRMovement")
308 FVRPlayerNetworkCorrectedSignature OnCharacterNetworkCorrected_Bind;
309
310 // Give my users direct access to an event for when the player state has changed
311 UPROPERTY(BlueprintAssignable, Category = "VRMovement")
312 FVRPlayerStateReplicatedSignature OnPlayerStateReplicated_Bind;
313
314 //These functions are now housed in the base character and used when possible, it saves about 7 bits of packet header overhead per send.
315
316 // I'm sending it unreliable because it is being resent pretty often
317 UFUNCTION(Unreliable, Server, WithValidation)
318 void Server_SendTransformCamera(FBPVRComponentPosRep NewTransform);
319
320 UFUNCTION(Unreliable, Server, WithValidation)
321 void Server_SendTransformLeftController(FBPVRComponentPosRep NewTransform);
322
323 UFUNCTION(Unreliable, Server, WithValidation)
324 void Server_SendTransformRightController(FBPVRComponentPosRep NewTransform);
325
326 virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override;
327
328 // If true will replicate the capsule height on to clients, allows for dynamic capsule height changes in multiplayer
329 UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRBaseCharacter")
330 bool VRReplicateCapsuleHeight;
331
332 // OnlyReplicated to simulated clients
333 UPROPERTY(Replicated, ReplicatedUsing = OnRep_CapsuleHeight)
334 FVRReplicatedCapsuleHeight ReplicatedCapsuleHeight;
336 UFUNCTION()
337 void OnRep_CapsuleHeight()
338 {
339 if (!VRReplicateCapsuleHeight)
340 return;
341
342 if (UCapsuleComponent * Capsule = Cast<UCapsuleComponent>(GetRootComponent()))
343 {
344 if (ReplicatedCapsuleHeight.CapsuleHeight > 0.0f && !FMath::IsNearlyEqual(ReplicatedCapsuleHeight.CapsuleHeight, Capsule->GetUnscaledCapsuleHalfHeight()))
345 {
346 SetCharacterHalfHeightVR(ReplicatedCapsuleHeight.CapsuleHeight, false);
347 }
349 }
350
351 // Override this in c++ or blueprints to pass in an IK mesh to be used in some optimizations
352 // May be extended in the future
353 //UFUNCTION(BlueprintNativeEvent, Category = "BaseVRCharacter")
354 //USkeletalMeshComponent * GetIKMesh() const;
355 //virtual USkeletalMeshComponent * GetIKMesh_Implementation() const;1
356 // #TODO: Work with the above, can do multiple things with it
357
358
359 // Called when the client is in climbing mode and is stepped up onto a platform
360 // Generally you should drop the climbing at this point and go into falling movement.
361 UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "VRMovement")
362 void OnClimbingSteppedUp();
363 virtual void OnClimbingSteppedUp_Implementation();
369 UFUNCTION(BlueprintNativeEvent, meta = (DisplayName = "UpdateLowGravMovement", ScriptName = "UpdateLowGravMovement"))
370 void UpdateLowGravMovement(float DeltaTime);
371 virtual void UpdateLowGravMovement_Implementation(float DeltaTime) {} // Do nothing by default
372
377 UFUNCTION(BlueprintNativeEvent, meta = (DisplayName = "UpdateClimbingMovement", ScriptName = "UpdateClimbingMovement"))
378 void UpdateClimbingMovement(float DeltaTime);
379 virtual void UpdateClimbingMovement_Implementation(float DeltaTime){} // Do nothing by default
380
381 // This is the offset location of the player, use this for when checking against player transform instead of the actors transform
382 UPROPERTY(BlueprintReadOnly, Transient, Category = "VRExpansionLibrary")
383 FTransform OffsetComponentToWorld;
384
385 // Gets the forward vector of the HMD offset capsule
386 UFUNCTION(BlueprintPure, Category = "BaseVRCharacter|VRLocations")
387 FVector GetVRForwardVector() const
388 {
389 return OffsetComponentToWorld.GetRotation().GetForwardVector();
390 }
391
392 // Gets the right vector of the HMD offset capsule
393 UFUNCTION(BlueprintPure, Category = "BaseVRCharacter|VRLocations")
394 FVector GetVRRightVector() const
395 {
396 return OffsetComponentToWorld.GetRotation().GetRightVector();
397 }
398
399 // Gets the upvector of the HMD offset capsule
400 UFUNCTION(BlueprintPure, Category = "BaseVRCharacter|VRLocations")
401 FVector GetVRUpVector() const
402 {
403 return OffsetComponentToWorld.GetRotation().GetUpVector();
404 }
405
406 // Gets the location of the HMD offset capsule (this retains the Capsule HalfHeight offset)
407 UFUNCTION(BlueprintPure, Category = "BaseVRCharacter|VRLocations")
408 FVector GetVRLocation() const
409 {
410 return OffsetComponentToWorld.GetLocation();
412
413 inline FVector GetVRLocation_Inline() const
414 {
415 return OffsetComponentToWorld.GetLocation();
416 }
417
418 // Gets the rotation of the HMD offset capsule
419 UFUNCTION(BlueprintPure, Category = "BaseVRCharacter|VRLocations")
420 FRotator GetVRRotation() const
421 {
422 return OffsetComponentToWorld.GetRotation().Rotator();
423 }
424 // Gets the location of the HMD, if the camera is missing then it just returns waist location instead
425 UFUNCTION(BlueprintPure, Category = "BaseVRCharacter|VRLocations", meta = (DisplayName = "GetVRHeadLocation", ScriptName = "GetVRHeadLocation", Keywords = "position"))
426 FVector K2_GetVRHeadLocation() const
427 {
428 return GetVRHeadLocation();
429 }
431 inline FVector GetVRHeadLocation() const
432 {
433 return VRReplicatedCamera != nullptr ? VRReplicatedCamera->GetComponentLocation() : OffsetComponentToWorld.GetLocation();
434 }
435
436
437 virtual FVector GetTargetLocation(AActor* RequestedBy) const override
438 {
439 return GetVRLocation_Inline();
440 }
441
442 // If true will use the experimental method of unseating that clears some movement replication options.
443 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRBaseCharacter")
444 bool bUseExperimentalUnseatModeFix;
445
446 UPROPERTY(BlueprintReadOnly, Replicated, EditAnywhere, Category = "Seating", ReplicatedUsing = OnRep_SeatedCharInfo)
447 FVRSeatedCharacterInfo SeatInformation;
448
449 // Called when the seated mode is changed
450 UFUNCTION(BlueprintNativeEvent, Category = "Seating")
451 void OnSeatedModeChanged(bool bNewSeatedMode, bool bWasAlreadySeated);
452 virtual void OnSeatedModeChanged_Implementation(bool bNewSeatedMode, bool bWasAlreadySeated) {}
453
454 // Called when the the player either transitions to/from the threshold boundry or the scaler value of being outside the boundry changes
455 // Can be used for warnings or screen darkening, ect
456 UFUNCTION(BlueprintNativeEvent, Category = "Seating")
457 void OnSeatThreshholdChanged(bool bIsWithinThreshold, float ToThresholdScaler);
458 virtual void OnSeatThreshholdChanged_Implementation(bool bIsWithinThreshold, float ToThresholdScaler) {}
459
460 // Call to use an object
461 UPROPERTY(BlueprintAssignable, Category = "Seating")
462 FVRSeatThresholdChangedSignature OnSeatThreshholdChanged_Bind;
463
464 void ZeroToSeatInformation()
465 {
466 SetSeatRelativeLocationAndRotationVR(FVector::ZeroVector);
467 NotifyOfTeleport();
468 //LeftMotionController->PostTeleportMoveGrippedObjects();
469 //RightMotionController->PostTeleportMoveGrippedObjects();
470 }
472 // Called from the movement component
473 void TickSeatInformation(float DeltaTime);
474
475 UFUNCTION()
476 virtual void OnRep_SeatedCharInfo();
477
478 void InitSeatedModeTransition();
479
480 // Re-zeros the seated settings
481 UFUNCTION(BlueprintCallable, Server, Reliable, WithValidation, Category = "BaseVRCharacter", meta = (DisplayName = "ReZeroSeating"))
482 void Server_ReZeroSeating(FTransform_NetQuantize NewTargetTransform, FTransform_NetQuantize NewInitialRelCameraTransform, bool bZeroToHead = true);
484
485 // Sets seated mode on the character and then fires off an event to handle any special setup
486 // Target Transform is for teleport location if standing up, or relative camera location when sitting down.
487 // InitialRelCameraTransform is generally the relative transform of the camera at the time of requesting to sit.
488 // ZeroToHead places central point on head, if false it will use foot location and ignore Z values instead.
489 // Post Seated movement mode is the movement mode to switch too after seating is canceled, defaults to Walking and only uses it when un-seating.
490 UFUNCTION(BlueprintCallable, Server, Reliable, WithValidation, Category = "BaseVRCharacter", meta = (DisplayName = "SetSeatedMode"))
491 void Server_SetSeatedMode(USceneComponent * SeatParent, bool bSetSeatedMode, FTransform_NetQuantize TargetTransform, FTransform_NetQuantize InitialRelCameraTransform, float AllowedRadius = 40.0f, float AllowedRadiusThreshold = 20.0f, bool bZeroToHead = true, EVRConjoinedMovementModes PostSeatedMovementMode = EVRConjoinedMovementModes::C_MOVE_Walking);
492
493 // Sets seated mode on the character and then fires off an event to handle any special setup
494 // Should only be called on the server / net authority
495 // If allowed radius is 0.0f then the seated mode does not check for radial distance anymore.
496 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);
497
498 void SetSeatRelativeLocationAndRotationVR(FVector LocDelta);
499
500 // Adds a rotation delta taking into account the HMD as a pivot point (also moves the actor), returns final location difference
501 UFUNCTION(BlueprintCallable, Category = "BaseVRCharacter|VRLocations")
502 FVector AddActorWorldRotationVR(FRotator DeltaRot, bool bUseYawOnly = true);
503
504 // Sets the actors rotation taking into account the HMD as a pivot point (also moves the actor), returns the location difference
505 // bAccountForHMDRotation sets the rot to have the HMD face the given rot, if it is false it ignores the HMD rotation
506 UFUNCTION(BlueprintCallable, Category = "BaseVRCharacter|VRLocations")
507 FVector SetActorRotationVR(FRotator NewRot, bool bUseYawOnly = true, bool bAccountForHMDRotation = true);
508
509 // Sets the actors rotation and location taking into account the HMD as a pivot point (also moves the actor), returns the location difference from the rotation
510 UFUNCTION(BlueprintCallable, Category = "BaseVRCharacter|VRLocations")
511 FVector SetActorLocationAndRotationVR(FVector NewLoc, FRotator NewRot, bool bUseYawOnly = true, bool bAccountForHMDRotation = true, bool bTeleport = false);
512
513 // Sets the actors location taking into account the HMD as a pivot point, returns the location difference
514 UFUNCTION(BlueprintCallable, Category = "BaseVRCharacter|VRLocations")
515 FVector SetActorLocationVR(FVector NewLoc, bool bTeleport);
516
517 // Regenerates the base offsetcomponenttoworld that VR uses
518 UFUNCTION(BlueprintCallable, Category = "BaseVRCharacter|VRLocations")
519 virtual void RegenerateOffsetComponentToWorld(bool bUpdateBounds, bool bCalculatePureYaw)
520 {}
521
522 // This sets the capsules height, but also regenerates the offset transform instantly
523 UFUNCTION(BlueprintCallable, Category = "BaseVRCharacter")
524 virtual void SetCharacterSizeVR(float NewRadius, float NewHalfHeight, bool bUpdateOverlaps = true);
525
526 // This sets the capsules half height, but also regenerates the offset transform instantly
527 UFUNCTION(BlueprintCallable, Category = "BaseVRCharacter")
528 virtual void SetCharacterHalfHeightVR(float HalfHeight, bool bUpdateOverlaps = true);
530 // This component is used with the normal character SkeletalMesh network smoothing system for simulated proxies
531 // It will lerp the characters components back to zero on simulated proxies after a move is complete.
532 // The simplest method of doing this was applying the exact same offset as the mesh gets to a base component that
533 // tracked objects are attached to.
534 UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
535 USceneComponent * NetSmoother;
536
537 // This is just a helper proxy component after the net smoother to make it easier to move tracking around for people
538 // but still maintain the netsmoothers functionality
539 UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
540 USceneComponent* VRProxyComponent;
541
542 UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, Transient, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
543 UVRBaseCharacterMovementComponent * VRMovementReference;
545 UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
546 UReplicatedVRCameraComponent * VRReplicatedCamera;
547
548 UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
549 UParentRelativeAttachmentComponent * ParentRelativeAttachment;
550
551 UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
552 UGripMotionControllerComponent * LeftMotionController;
553
554 UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
555 UGripMotionControllerComponent * RightMotionController;
556
558 static FName LeftMotionControllerComponentName;
559
561 static FName RightMotionControllerComponentName;
562
564 static FName ReplicatedCameraComponentName;
565
567 static FName ParentRelativeAttachmentComponentName;
570 static FName SmoothingSceneParentComponentName;
571
573 static FName VRProxyComponentName;
575 /*
576 A helper function that offsets a given vector by the roots collision location
577 pass in a teleport location and it provides the correct spot for it to be at your feet
578 */
579 UFUNCTION(BlueprintPure, Category = "VRGrip")
580 virtual FVector GetTeleportLocation(FVector OriginalLocation);
581
582 // Notifies that we should teleport the both hand grips on next tick
583 // When called server side will automatically apply to remote clients as well.
584 // Owning clients get it on server correction automatically already.
585 UFUNCTION(BlueprintCallable, Category = "VRGrip")
586 virtual void NotifyOfTeleport(bool bRegisterAsTeleport = true);
587
588
589 // Event triggered when a move action is performed, this is ran just prior to PerformMovement in the character tick
590 UFUNCTION(BlueprintNativeEvent, Category = "VRMovement")
591 void OnCustomMoveActionPerformed(EVRMoveAction MoveActionType, FVector MoveActionVector, FRotator MoveActionRotator, uint8 MoveActionFlags);
592 virtual void OnCustomMoveActionPerformed_Implementation(EVRMoveAction MoveActionType, FVector MoveActionVector, FRotator MoveActionRotator, uint8 MoveActionFlags);
594 // Event triggered when beginning to be pushed back from a wall
595 // bHadLocomotionInput means that the character was moving itself
596 // HmdInput is how much the HMD moved in that tick so you can compare sizes to decide what to do
597 UFUNCTION(BlueprintNativeEvent, Category = "VRMovement")
598 void OnBeginWallPushback(FHitResult HitResultOfImpact, bool bHadLocomotionInput, FVector HmdInput);
599 virtual void OnBeginWallPushback_Implementation(FHitResult HitResultOfImpact, bool bHadLocomotionInput, FVector HmdInput);
601 // Event triggered when beginning to be pushed back from a wall
602 UFUNCTION(BlueprintNativeEvent, Category = "VRMovement")
603 void OnEndWallPushback();
604 virtual void OnEndWallPushback_Implementation();
605
606 // Event when a navigation pathing operation has completed, auto calls stop movement for VR characters
607 UFUNCTION(BlueprintImplementableEvent, Category = "VRBaseCharacter|Navigation")
608 void ReceiveNavigationMoveCompleted(EPathFollowingResult::Type PathingResult);
610 virtual void NavigationMoveCompleted(FAIRequestID RequestID, const FPathFollowingResult& Result)
611 {
612 this->Controller->StopMovement();
613 ReceiveNavigationMoveCompleted(Result.Code);
614 }
615
616 UFUNCTION(BlueprintCallable, Category = "VRBaseCharacter|Navigation")
617 EPathFollowingStatus::Type GetMoveStatus() const
618 {
620 return EPathFollowingStatus::Idle;
621
622 if (UPathFollowingComponent* pathComp = Controller->FindComponentByClass<UPathFollowingComponent>())
623 {
624 pathComp->GetStatus();
625 }
626
627 return EPathFollowingStatus::Idle;
628 }
629
631 UFUNCTION(BlueprintCallable, Category = "VRBaseCharacter|Navigation")
632 bool HasPartialPath() const
633 {
634 if (!Controller)
635 return false;
636
637 if (UPathFollowingComponent* pathComp = Controller->FindComponentByClass<UPathFollowingComponent>())
638 {
639 return pathComp->HasPartialPath();
640 }
641
642 return false;
643 }
644
645 // Instantly stops pathing
646 UFUNCTION(BlueprintCallable, Category = "VRBaseCharacter|Navigation")
647 void StopNavigationMovement()
648 {
649 if (!Controller)
650 return;
651
652 if (UPathFollowingComponent* pathComp = Controller->FindComponentByClass<UPathFollowingComponent>())
653 {
654 // @note FPathFollowingResultFlags::ForcedScript added to make AITask_MoveTo instances
655 // not ignore OnRequestFinished notify that's going to be sent out due to this call
656 pathComp->AbortMove(*this, FPathFollowingResultFlags::MovementStop | FPathFollowingResultFlags::ForcedScript);
657 }
658 }
659
660 UPROPERTY(BlueprintReadWrite, Category = AI)
661 TSubclassOf<UNavigationQueryFilter> DefaultNavigationFilterClass;
662
663 // An extended simple move to location with additional parameters
664 UFUNCTION(BlueprintCallable, Category = "VRBaseCharacter|Navigation", Meta = (AdvancedDisplay = "bStopOnOverlap,bCanStrafe,bAllowPartialPath"))
665 virtual void ExtendedSimpleMoveToLocation(const FVector& GoalLocation, float AcceptanceRadius = -1, bool bStopOnOverlap = false,
666 bool bUsePathfinding = true, bool bProjectDestinationToNavigation = true, bool bCanStrafe = false,
667 TSubclassOf<UNavigationQueryFilter> FilterClass = NULL, bool bAllowPartialPath = true);
668
669 // Returns the current path points on the active navigation path
670 // Will return false / an empty result if the path following component is not active yet or the path is empty
671 UFUNCTION(BlueprintCallable, Category = "VRBaseCharacter|Navigation")
672 bool GetCurrentNavigationPathPoints(TArray<FVector>& NavigationPointList);
673
674};
EVRMoveAction
UENUM(Blueprintable)
EVRConjoinedMovementModes
UENUM(BlueprintType)
DECLARE_LOG_CATEGORY_EXTERN(LogBaseVRCharacter, Log, All)
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FVRSeatThresholdChangedSignature, bool, bIsWithinThreshold, float, ToThresholdScaler)
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FVRPlayerTeleportedSignature)
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FVRPlayerStateReplicatedSignature, const APlayerState *, NewPlayerState)
FVRSeatedCharacterInfo SeatInformation
UPROPERTY(BlueprintReadOnly, Replicated, EditAnywhere, Category = "Seating", ReplicatedUsing = OnRep_...
virtual FVector GetTargetLocation(AActor *RequestedBy) const override
void StopNavigationMovement()
UFUNCTION(BlueprintCallable, Category = "VRBaseCharacter|Navigation")
USceneComponent * VRProxyComponent
UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess ...
FVRReplicatedCapsuleHeight ReplicatedCapsuleHeight
UPROPERTY(Replicated, ReplicatedUsing = OnRep_CapsuleHeight)
FVRSeatThresholdChangedSignature OnSeatThreshholdChanged_Bind
UPROPERTY(BlueprintAssignable, Category = "Seating")
static FName ReplicatedCameraComponentName
FVRPlayerNetworkCorrectedSignature OnCharacterNetworkCorrected_Bind
UPROPERTY(BlueprintAssignable, Category = "VRMovement")
void OnSeatedModeChanged(bool bNewSeatedMode, bool bWasAlreadySeated)
UFUNCTION(BlueprintNativeEvent, Category = "Seating")
FRotator GetVRRotation() const
UFUNCTION(BlueprintPure, Category = "BaseVRCharacter|VRLocations")
void OnEndWallPushback()
UFUNCTION(BlueprintNativeEvent, Category = "VRMovement")
USceneComponent * NetSmoother
UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess ...
virtual void UpdateLowGravMovement_Implementation(float DeltaTime)
UGripMotionControllerComponent * RightMotionController
UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess ...
FVector GetVRForwardVector() const
UFUNCTION(BlueprintPure, Category = "BaseVRCharacter|VRLocations")
void OnCustomMoveActionPerformed(EVRMoveAction MoveActionType, FVector MoveActionVector, FRotator MoveActionRotator, uint8 MoveActionFlags)
UFUNCTION(BlueprintNativeEvent, Category = "VRMovement")
FVRPlayerTeleportedSignature OnCharacterTeleported_Bind
UPROPERTY(BlueprintAssignable, Category = "VRMovement")
static FName LeftMotionControllerComponentName
virtual void OnSeatedModeChanged_Implementation(bool bNewSeatedMode, bool bWasAlreadySeated)
bool HasPartialPath() const
UFUNCTION(BlueprintCallable, Category = "VRBaseCharacter|Navigation")
void ReceiveNavigationMoveCompleted(EPathFollowingResult::Type PathingResult)
UFUNCTION(BlueprintImplementableEvent, Category = "VRBaseCharacter|Navigation")
virtual void OnSeatThreshholdChanged_Implementation(bool bIsWithinThreshold, float ToThresholdScaler)
void Server_SendTransformRightController(FBPVRComponentPosRep NewTransform)
UFUNCTION(Unreliable, Server, WithValidation)
FVector GetVRLocation() const
UFUNCTION(BlueprintPure, Category = "BaseVRCharacter|VRLocations")
void OnRep_CapsuleHeight()
UFUNCTION()
virtual void UpdateClimbingMovement_Implementation(float DeltaTime)
FVector K2_GetVRHeadLocation() const
UFUNCTION(BlueprintPure, Category = "BaseVRCharacter|VRLocations", meta = (DisplayName = "GetVRHeadLo...
static FName VRProxyComponentName
static FName SmoothingSceneParentComponentName
FTransform OffsetComponentToWorld
UPROPERTY(BlueprintReadOnly, Transient, Category = "VRExpansionLibrary")
static FName RightMotionControllerComponentName
FVector GetVRRightVector() const
UFUNCTION(BlueprintPure, Category = "BaseVRCharacter|VRLocations")
virtual void NavigationMoveCompleted(FAIRequestID RequestID, const FPathFollowingResult &Result)
void OnBeginWallPushback(FHitResult HitResultOfImpact, bool bHadLocomotionInput, FVector HmdInput)
UFUNCTION(BlueprintNativeEvent, Category = "VRMovement")
void Server_ReZeroSeating(FTransform_NetQuantize NewTargetTransform, FTransform_NetQuantize NewInitialRelCameraTransform, bool bZeroToHead=true)
UFUNCTION(BlueprintCallable, Server, Reliable, WithValidation, Category = "BaseVRCharacter",...
void UpdateClimbingMovement(float DeltaTime)
UFUNCTION(BlueprintNativeEvent, meta = (DisplayName = "UpdateClimbingMovement", ScriptName = "UpdateC...
FVRPlayerStateReplicatedSignature OnPlayerStateReplicated_Bind
UPROPERTY(BlueprintAssignable, Category = "VRMovement")
bool VRReplicateCapsuleHeight
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRBaseCharacter")
static FName ParentRelativeAttachmentComponentName
FVector GetVRUpVector() const
UFUNCTION(BlueprintPure, Category = "BaseVRCharacter|VRLocations")
UVRBaseCharacterMovementComponent * VRMovementReference
UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, Transient, BlueprintReadOnly,...
UReplicatedVRCameraComponent * VRReplicatedCamera
UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess ...
TSubclassOf< UNavigationQueryFilter > DefaultNavigationFilterClass
UPROPERTY(BlueprintReadWrite, Category = AI)
virtual void RegenerateOffsetComponentToWorld(bool bUpdateBounds, bool bCalculatePureYaw)
UFUNCTION(BlueprintCallable, Category = "BaseVRCharacter|VRLocations")
void UpdateLowGravMovement(float DeltaTime)
UFUNCTION(BlueprintNativeEvent, meta = (DisplayName = "UpdateLowGravMovement", ScriptName = "UpdateLo...
UGripMotionControllerComponent * LeftMotionController
UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess ...
void OnSeatThreshholdChanged(bool bIsWithinThreshold, float ToThresholdScaler)
UFUNCTION(BlueprintNativeEvent, Category = "Seating")
EPathFollowingStatus::Type GetMoveStatus() const
UFUNCTION(BlueprintCallable, Category = "VRBaseCharacter|Navigation")
void OnClimbingSteppedUp()
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "VRMovement")
bool bUseExperimentalUnseatModeFix
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRBaseCharacter")
void Server_SetSeatedMode(USceneComponent *SeatParent, bool bSetSeatedMode, FTransform_NetQuantize TargetTransform, FTransform_NetQuantize InitialRelCameraTransform, float AllowedRadius=40.0f, float AllowedRadiusThreshold=20.0f, bool bZeroToHead=true, EVRConjoinedMovementModes PostSeatedMovementMode=EVRConjoinedMovementModes::C_MOVE_Walking)
UFUNCTION(BlueprintCallable, Server, Reliable, WithValidation, Category = "BaseVRCharacter",...
UParentRelativeAttachmentComponent * ParentRelativeAttachment
UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess ...
void Server_SendTransformLeftController(FBPVRComponentPosRep NewTransform)
UFUNCTION(Unreliable, Server, WithValidation)
AVRPlayerController * OwningVRPlayerController
UPROPERTY(Transient, DuplicateTransient)
FVector GetVRLocation_Inline() const
FVector GetVRHeadLocation() const
void Server_SendTransformCamera(FBPVRComponentPosRep NewTransform)
UFUNCTION(Unreliable, Server, WithValidation)
UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent), ClassGroup = MotionController)
UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent), ClassGroup = VRExpansionLibrary)
UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent), ClassGroup = VRExpansionLibrary)
bool bJustTeleported
UPROPERTY(Transient)
bool bJustTeleportedGrips
UPROPERTY(Transient)
bool NetSerialize(FArchive &Ar, class UPackageMap *Map, bool &bOutSuccess)
AActor * Owner
UPROPERTY(Transient)
FVector_NetQuantize100 PausedTrackingLoc
UPROPERTY(Transient)
bool bPausedTracking
UPROPERTY(Transient)
float PausedTrackingRot
UPROPERTY(Transient)
USTRUCT(BlueprintType, Category = "VRExpansionLibrary|TransformNetQuantize", meta = (HasNativeMake = ...
bool NetSerialize(FArchive &Ar, class UPackageMap *Map, bool &bOutSuccess)
bool NetSerialize(FArchive &Ar, class UPackageMap *Map, bool &bOutSuccess)
USTRUCT(Blueprintable)
FTransform_NetQuantize StoredTargetTransform
UPROPERTY(BlueprintReadOnly, Category = "CharacterSeatInfo")
float AllowedRadius
UPROPERTY(EditAnywhere, BlueprintReadWrite, NotReplicated, Category = "CharacterSeatInfo",...
bool NetSerialize(FArchive &Ar, class UPackageMap *Map, bool &bOutSuccess)
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",...