15#include "GameFramework/PhysicsVolume.h"
20 : Super(ObjectInitializer)
22 PrimaryComponentTick.TickGroup = TG_PrePhysics;
61 NetworkSmoothingMode = ENetworkSmoothingMode::Exponential;
69 bEnableServerDualMoveScopedMovementUpdates =
true;
99 BaseOwner->InitSeatedModeTransition();
104 if (MovementMode == EMovementMode::MOVE_Custom)
109 StopMovementKeepPathing();
110 CharacterOwner->ResetJumpState();
111 ClearAccumulatedForces();
117 BaseOwner->InitSeatedModeTransition();
123 Super::OnMovementModeChanged(PreviousMovementMode, PreviousCustomMode);
134 return Super::ForcePositionUpdate(DeltaTime);
172 FVRCharacterScopedMovementUpdate ScopedMovementUpdate(UpdatedComponent, bEnableScopedMovementUpdates ? EScopedUpdate::DeferredUpdates : EScopedUpdate::ImmediateUpdates);
176 const FVector InputVector = ConsumeInputVector();
177 if (!HasValidData() || ShouldSkipUpdate(DeltaTime))
183 Super::Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
186 const bool bIsSimulatingPhysics = UpdatedComponent->IsSimulatingPhysics();
187 if (CharacterOwner->GetLocalRole() == ROLE_Authority && (!bCheatFlying || bIsSimulatingPhysics) && !CharacterOwner->CheckStillInWorld())
193 if (CharacterOwner->GetLocalRole() > ROLE_SimulatedProxy)
198 BaseChar->TickSeatInformation(DeltaTime);
201 if (CharacterOwner && !CharacterOwner->IsLocallyControlled() && DeltaTime > 0.0f)
204 if (!CharacterOwner->bClientUpdating && !CharacterOwner->IsPlayingRootMotion() && CharacterOwner->GetMesh())
206 TickCharacterPose(DeltaTime);
210 CharacterOwner->GetMesh()->ConditionallyDispatchQueuedAnimEvents();
217 if (bNetworkUpdateReceived)
219 if (bNetworkMovementModeChanged)
222 bNetworkMovementModeChanged =
false;
228 Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
233 if (
UVRRootComponent* VRRoot = Cast<UVRRootComponent>(CharacterOwner->GetCapsuleComponent()))
237 if (!VRRoot->bCalledUpdateTransform)
238 VRRoot->OnUpdateTransform_Public(EUpdateTransformFlags::None, ETeleportType::None);
253 if (OwningController)
266 if (OuterScopeCamera)
294 return Super::VerifyClientTimeStamp(TimeStamp, ServerData);
306 if (
AVRBaseCharacter * OwningCharacter = Cast<AVRBaseCharacter>(GetCharacterOwner()))
308 OwningCharacter->OnBeginWallPushback(HitResult, !Acceleration.Equals(FVector::ZeroVector),
AdditionalVRInputVector);
320 if (
AVRBaseCharacter * OwningCharacter = Cast<AVRBaseCharacter>(GetCharacterOwner()))
322 OwningCharacter->OnEndWallPushback();
328 if (
AVRBaseCharacter * BaseCharacter = Cast<AVRBaseCharacter>(GetCharacterOwner()))
330 return UpdatedComponent ? (BaseCharacter->OffsetComponentToWorld.GetLocation() - FVector(0, 0, UpdatedComponent->Bounds.BoxExtent.Z)) : FNavigationSystem::InvalidLocation;
334 return UpdatedComponent ? (UpdatedComponent->GetComponentLocation() - FVector(0, 0, UpdatedComponent->Bounds.BoxExtent.Z)) : FNavigationSystem::InvalidLocation;
340 if (
AVRBaseCharacter* vrOwner = Cast<AVRBaseCharacter>(GetCharacterOwner()))
342 vrOwner->NavigationMoveCompleted(RequestID, Result);
348 UE_LOG(LogVRBaseCharacterMovement, VeryVerbose, TEXT(
"[Role:%d] ComputeFloorDist: %s at location %s"), (int32)CharacterOwner->GetLocalRole(), *GetNameSafe(CharacterOwner), *CapsuleLocation.ToString());
349 OutFloorResult.Clear();
351 float PawnRadius, PawnHalfHeight;
352 CharacterOwner->GetCapsuleComponent()->GetScaledCapsuleSize(PawnRadius, PawnHalfHeight);
354 bool bSkipSweep =
false;
355 if (DownwardSweepResult != NULL && DownwardSweepResult->IsValidBlockingHit())
358 if ((DownwardSweepResult->TraceStart.Z > DownwardSweepResult->TraceEnd.Z) &&
359 (DownwardSweepResult->TraceStart - DownwardSweepResult->TraceEnd).SizeSquared2D() <= KINDA_SMALL_NUMBER)
362 if (IsWithinEdgeTolerance(DownwardSweepResult->Location, DownwardSweepResult->ImpactPoint, PawnRadius))
367 const bool bIsWalkable = IsWalkable(*DownwardSweepResult);
368 const float FloorDist = (CapsuleLocation.Z - DownwardSweepResult->Location.Z);
369 OutFloorResult.SetFromSweep(*DownwardSweepResult, FloorDist, bIsWalkable);
381 if (SweepDistance < LineDistance)
383 ensure(SweepDistance >= LineDistance);
387 bool bBlockingHit =
false;
388 FCollisionQueryParams QueryParams(SCENE_QUERY_STAT(
ComputeFloorDist),
false, CharacterOwner);
389 FCollisionResponseParams ResponseParam;
390 InitCollisionParams(QueryParams, ResponseParam);
391 const ECollisionChannel CollisionChannel = UpdatedComponent->GetCollisionObjectType();
395 ResponseParam.CollisionResponse.PhysicsBody = ECollisionResponse::ECR_Ignore;
398 if (!bSkipSweep && SweepDistance > 0.f && SweepRadius > 0.f)
402 const float ShrinkScale = 0.9f;
403 const float ShrinkScaleOverlap = 0.1f;
404 float ShrinkHeight = (PawnHalfHeight - PawnRadius) * (1.f - ShrinkScale);
405 float TraceDist = SweepDistance + ShrinkHeight;
406 FCollisionShape CapsuleShape = FCollisionShape::MakeCapsule(SweepRadius, PawnHalfHeight - ShrinkHeight);
409 bBlockingHit = FloorSweepTest(Hit, CapsuleLocation, CapsuleLocation + FVector(0.f, 0.f, -TraceDist), CollisionChannel, CapsuleShape, QueryParams, ResponseParam);
415 if (Hit.bStartPenetrating || !IsWithinEdgeTolerance(CapsuleLocation, Hit.ImpactPoint, CapsuleShape.Capsule.Radius))
419 CapsuleShape.Capsule.Radius = FMath::Max(0.f, CapsuleShape.Capsule.Radius - SWEEP_EDGE_REJECT_DISTANCE - KINDA_SMALL_NUMBER);
420 if (!CapsuleShape.IsNearlyZero())
422 ShrinkHeight = (PawnHalfHeight - PawnRadius) * (1.f - ShrinkScaleOverlap);
423 TraceDist = SweepDistance + ShrinkHeight;
424 CapsuleShape.Capsule.HalfHeight = FMath::Max(PawnHalfHeight - ShrinkHeight, CapsuleShape.Capsule.Radius);
425 Hit.Reset(1.f,
false);
427 bBlockingHit = FloorSweepTest(Hit, CapsuleLocation, CapsuleLocation + FVector(0.f, 0.f, -TraceDist), CollisionChannel, CapsuleShape, QueryParams, ResponseParam);
433 const float MaxPenetrationAdjust = FMath::Max(MAX_FLOOR_DIST, PawnRadius);
434 const float SweepResult = FMath::Max(-MaxPenetrationAdjust, Hit.Time * TraceDist - ShrinkHeight);
436 OutFloorResult.SetFromSweep(Hit, SweepResult,
false);
437 if (Hit.IsValidBlockingHit() && IsWalkable(Hit))
439 if (SweepResult <= SweepDistance)
442 OutFloorResult.bWalkableFloor =
true;
451 if (!OutFloorResult.bBlockingHit && !OutFloorResult.HitResult.bStartPenetrating)
453 OutFloorResult.FloorDist = SweepDistance;
458 if (LineDistance > 0.f)
460 const float ShrinkHeight = PawnHalfHeight;
461 const FVector LineTraceStart = CapsuleLocation;
462 const float TraceDist = LineDistance + ShrinkHeight;
463 const FVector Down = FVector(0.f, 0.f, -TraceDist);
464 QueryParams.TraceTag = SCENE_QUERY_STAT_NAME_ONLY(FloorLineTrace);
467 bBlockingHit = GetWorld()->LineTraceSingleByChannel(Hit, LineTraceStart, LineTraceStart + Down, CollisionChannel, QueryParams, ResponseParam);
475 const float MaxPenetrationAdjust = FMath::Max(MAX_FLOOR_DIST, PawnRadius);
476 const float LineResult = FMath::Max(-MaxPenetrationAdjust, Hit.Time * TraceDist - ShrinkHeight);
478 OutFloorResult.bBlockingHit =
true;
479 if (LineResult <= LineDistance && IsWalkable(Hit))
481 OutFloorResult.SetFromLineTrace(Hit, OutFloorResult.FloorDist, LineResult,
true);
489 OutFloorResult.bWalkableFloor =
false;
497 if (!Hit.bBlockingHit)
502 FVector Normal(InNormal);
503 if (IsMovingOnGround())
508 if (!IsWalkable(Hit))
510 Normal = Normal.GetSafeNormal2D();
513 else if (Normal.Z < -KINDA_SMALL_NUMBER)
516 if (CurrentFloor.FloorDist < MIN_FLOOR_DIST && CurrentFloor.bBlockingHit)
518 const FVector FloorNormal = CurrentFloor.HitResult.Normal;
519 const bool bFloorOpposedToMovement = (Delta | FloorNormal) < 0.f && (FloorNormal.Z < 1.f - DELTA);
520 if (bFloorOpposedToMovement)
522 Normal = FloorNormal;
525 Normal = Normal.GetSafeNormal2D();
542 return Super::Super::SlideAlongSurface(Delta *
VRWallSlideScaler, Time, Normal, Hit, bHandleImpact);
544 return Super::Super::SlideAlongSurface(Delta, Time, Normal, Hit, bHandleImpact);
551 this->CrouchedHalfHeight = NewCrouchedHalfHeight;
557 if (GetNetMode() == NM_Client)
572 if (GetNetMode() < NM_Client)
575 if (OwningChar && !OwningChar->IsLocallyControlled())
607 MoveAction.
MoveActionRot = FRotator(0.0f, FRotator::DecompressAxisFromShort(FRotator::CompressAxisToShort((FRotator(0.f, DeltaYawAngle, 0.f).Quaternion() * UpdatedComponent->GetComponentQuat()).Rotator().Yaw)), 0.0f);
609 if (bFlagCharacterTeleport)
611 else if(bFlagGripTeleport)
630 MoveAction.
MoveActionRot = FRotator(0.0f, FMath::RoundToFloat(NewYaw * 100.f) / 100.f, 0.0f);
632 if (bFlagCharacterTeleport)
634 else if (bFlagGripTeleport)
639 float DeltaYawAngle = FMath::FindDeltaAngleDegrees(UpdatedComponent->GetComponentRotation().Yaw, NewYaw);
655 MoveAction.
MoveActionRot.Yaw = FMath::RoundToFloat(TeleportRotation.Yaw * 100.f) / 100.f;
660 float DeltaYawAngle = FMath::FindDeltaAngleDegrees(UpdatedComponent->GetComponentRotation().Yaw, TeleportRotation.Yaw);
699 switch (MoveAction.MoveAction)
725 if (
AVRBaseCharacter * OwningCharacter = Cast<AVRBaseCharacter>(GetCharacterOwner()))
727 OwningCharacter->OnCustomMoveActionPerformed(MoveAction.MoveAction, MoveAction.MoveActionLoc, MoveAction.MoveActionRot, MoveAction.MoveActionFlags);
738 if (
AVRBaseCharacter * OwningCharacter = Cast<AVRBaseCharacter>(GetCharacterOwner()))
743 FQuat OrigRot = OwningCharacter->GetActorQuat();
749 MoveAction.
MoveActionLoc = OwningCharacter->SetActorRotationVR(TargetRot,
true,
false);
754 OwningCharacter->SetActorRotationVR(TargetRot,
true,
false);
761 OwningCharacter->SetActorLocation(OwningCharacter->GetActorLocation() + MoveAction.
MoveActionLoc);
765 OwningCharacter->SetActorRotationVR(TargetRot,
true,
false);
777 this->Velocity = FVector::ZeroVector;
781 if (OwningCharacter->IsLocallyControlled())
805 if (
AVRBaseCharacter * OwningCharacter = Cast<AVRBaseCharacter>(GetCharacterOwner()))
812 MoveAction.
MoveActionLoc = OwningCharacter->SetActorRotationVR(TargetRot,
true);
817 OwningCharacter->SetActorRotationVR(TargetRot,
true);
824 OwningCharacter->SetActorLocation(OwningCharacter->GetActorLocation() + MoveAction.
MoveActionLoc);
828 OwningCharacter->SetActorRotationVR(TargetRot,
true);
840 this->Velocity = FVector::ZeroVector;
844 if (OwningCharacter->IsLocallyControlled())
868 if (
AVRBaseCharacter * OwningCharacter = Cast<AVRBaseCharacter>(GetCharacterOwner()))
870 AController* OwningController = OwningCharacter->GetController();
872 if (!OwningController)
880 OwningCharacter->TeleportTo(MoveAction.
MoveActionLoc, TargetRot,
false, bSkipEncroachmentCheck);
890 this->Velocity = FVector::ZeroVector;
894 if (OwningCharacter->IsLocallyControlled())
906 if (OwningCharacter->bUseControllerRotationYaw)
907 OwningController->SetControlRotation(TargetRot);
917 if (
AVRBaseCharacter * OwningCharacter = Cast<AVRBaseCharacter>(GetCharacterOwner()))
919 this->StopMovementImmediately();
928 if (
AVRBaseCharacter* OwningCharacter = Cast<AVRBaseCharacter>(GetCharacterOwner()))
931 OwningCharacter->PausedTrackingLoc = MoveAction.
MoveActionLoc;
932 OwningCharacter->PausedTrackingRot = MoveAction.
MoveActionRot.Yaw;
951 Super::PhysCustom(deltaTime, Iterations);
958 return StepUp(GravDir, Delta, InHit, OutStepDownResult);
963 if (deltaTime < MIN_TICK_TIME)
980 Velocity = FVector::ZeroVector;
986 bJustTeleported =
false;
988 FVector OldLocation = UpdatedComponent->GetComponentLocation();
991 bool bZeroDelta = Delta.IsNearlyZero();
993 FStepDownResult StepDownResult;
997 float OldMaxStepHeight = MaxStepHeight;
999 bool bSteppedUp =
false;
1003 FHitResult Hit(1.f);
1004 SafeMoveUpdatedComponent(Delta, UpdatedComponent->GetComponentQuat(),
true, Hit);
1008 const FVector GravDir = FVector(0.f, 0.f, -1.f);
1010 const float UpDown = GravDir | VelDir;
1013 if ((FMath::Abs(Hit.ImpactNormal.Z) < 0.2f) && (UpDown < 0.5f) && (UpDown > -0.2f) && CanStepUp(Hit))
1018 float stepZ = UpdatedComponent->GetComponentLocation().Z;
1028 FVector finalLoc = UpdatedComponent->GetComponentLocation();
1034 MaxStepHeight = OldMaxStepHeight;
1042 OldLocation.Z = UpdatedComponent->GetComponentLocation().Z + (OldLocation.Z - stepZ);
1050 HandleImpact(Hit, deltaTime, Adjusted);
1057 MaxStepHeight = OldMaxStepHeight;
1061 if (
AVRBaseCharacter * ownerCharacter = Cast<AVRBaseCharacter>(CharacterOwner))
1070 Velocity = FVector::ZeroVector;
1074 ownerCharacter->OnClimbingSteppedUp();
1080 if (StepDownResult.bComputedFloor)
1082 CurrentFloor = StepDownResult.FloorResult;
1086 FindFloor(UpdatedComponent->GetComponentLocation(), CurrentFloor, bZeroDelta, NULL);
1089 if (CurrentFloor.IsWalkableFloor())
1091 if(CurrentFloor.GetDistanceToFloor() < (MIN_FLOOR_DIST + MAX_FLOOR_DIST) / 2)
1092 AdjustFloorHeight();
1097 else if (CurrentFloor.HitResult.bStartPenetrating)
1101 FHitResult Hit(CurrentFloor.HitResult);
1102 Hit.TraceEnd = Hit.TraceStart + FVector(0.f, 0.f, MAX_FLOOR_DIST);
1103 const FVector RequestedAdjustment = GetPenetrationAdjustment(Hit);
1104 ResolvePenetration(RequestedAdjustment, Hit, UpdatedComponent->GetComponentQuat());
1105 bForceNextFloorCheck =
true;
1110 if (!bJustTeleported && !HasAnimRootMotion() && !CurrentRootMotion.HasOverrideVelocity())
1120 if (deltaTime < MIN_TICK_TIME)
1126 if (CharacterOwner->IsLocallyControlled())
1129 if (
AVRBaseCharacter * characterOwner = Cast<AVRBaseCharacter>(CharacterOwner))
1131 characterOwner->UpdateLowGravMovement(deltaTime);
1135 float Friction = 0.0f;
1144 Friction = 0.5f * GetPhysicsVolume()->FluidFriction;
1146 CalcVelocity(deltaTime, Friction,
true, 0.0f);
1155 bJustTeleported =
false;
1157 FVector OldLocation = UpdatedComponent->GetComponentLocation();
1158 const FVector Adjusted = (Velocity * deltaTime);
1159 FHitResult Hit(1.f);
1160 SafeMoveUpdatedComponent(Adjusted, UpdatedComponent->GetComponentQuat(),
true, Hit);
1165 const FVector GravDir = FVector(0.f, 0.f, -1.f);
1166 const FVector VelDir = Velocity.GetSafeNormal();
1167 const float UpDown = GravDir | VelDir;
1169 bool bSteppedUp =
false;
1170 if ((FMath::Abs(Hit.ImpactNormal.Z) < 0.2f) && (UpDown < 0.5f) && (UpDown > -0.2f) && CanStepUp(Hit))
1172 float stepZ = UpdatedComponent->GetComponentLocation().Z;
1173 bSteppedUp = StepUp(GravDir, Adjusted * (1.f - Hit.Time), Hit);
1176 OldLocation.Z = UpdatedComponent->GetComponentLocation().Z + (OldLocation.Z - stepZ);
1183 HandleImpact(Hit, deltaTime, Adjusted);
1187 if (!bJustTeleported && !HasAnimRootMotion() && !CurrentRootMotion.HasOverrideVelocity())
1194 if (!bJustTeleported && !HasAnimRootMotion() && !CurrentRootMotion.HasOverrideVelocity())
1196 Velocity = (((UpdatedComponent->GetComponentLocation() - OldLocation) ) / deltaTime);
1220 if (MovementMode == EMovementMode::MOVE_Custom)
1230 if (CharacterOwner->GetLocalRole() != ENetRole::ROLE_SimulatedProxy)
1232 const uint8 CurrentPackedMovementMode = PackNetworkMovementMode();
1233 if (CurrentPackedMovementMode != ReceivedMode)
1235 TEnumAsByte<EMovementMode> NetMovementMode(MOVE_None);
1236 TEnumAsByte<EMovementMode> NetGroundMode(MOVE_None);
1237 uint8 NetCustomMode(0);
1238 UnpackNetworkMovementMode(ReceivedMode, NetMovementMode, NetCustomMode, NetGroundMode);
1241 if (NetMovementMode == EMovementMode::MOVE_Custom || MovementMode == EMovementMode::MOVE_Custom)
1249 Super::ApplyNetworkMovementMode(ReceivedMode);
1362 Super::SetUpdatedComponent(NewUpdatedComponent);
1371 FVRCharacterScopedMovementUpdate ScopedMovementUpdate(UpdatedComponent, bEnableScopedMovementUpdates ? EScopedUpdate::DeferredUpdates : EScopedUpdate::ImmediateUpdates);
1394 Super::PerformMovement(DeltaSeconds);
1403 if (CharacterOwner->GetLocalRole() == ROLE_Authority)
1411 Super::OnClientCorrectionReceived(ClientData, TimeStamp, NewLocation, NewVelocity, NewBase, NewBaseBoneName, bHasBase, bBaseRelativePosition, ServerMovementMode);
1428 QUICK_SCOPE_CYCLE_COUNTER(STAT_Character_CharacterMovementSimulated);
1429 checkSlow(CharacterOwner !=
nullptr);
1431 if (NetworkSmoothingMode == ENetworkSmoothingMode::Replay)
1433 const FVector OldLocation = UpdatedComponent ? UpdatedComponent->GetComponentLocation() : FVector::ZeroVector;
1434 const FVector OldVelocity = Velocity;
1438 QUICK_SCOPE_CYCLE_COUNTER(STAT_Character_CharacterMovementSmoothClientPosition);
1445 UpdateComponentVelocity();
1446 bJustTeleported =
false;
1450 CharacterOwner->RootMotionRepMoves.Empty();
1451 CurrentRootMotion.Clear();
1452 CharacterOwner->SavedRootMotion.Clear();
1457 OnMovementUpdated(DeltaSeconds, OldLocation, OldVelocity);
1458 CallMovementUpdateDelegate(DeltaSeconds, OldLocation, OldVelocity);
1460 LastUpdateLocation = UpdatedComponent ? UpdatedComponent->GetComponentLocation() : FVector::ZeroVector;
1461 LastUpdateRotation = UpdatedComponent ? UpdatedComponent->GetComponentQuat() : FQuat::Identity;
1462 LastUpdateVelocity = Velocity;
1469 if (CharacterOwner->IsPlayingNetworkedRootMotionMontage())
1471 bWasSimulatingRootMotion =
true;
1472 UE_LOG(LogRootMotion, Verbose, TEXT(
"UCharacterMovementComponent::SimulatedTick"));
1475 if (CharacterOwner && CharacterOwner->GetMesh())
1477 TickCharacterPose(DeltaSeconds);
1480 if (!HasValidData())
1486 if (RootMotionParams.bHasRootMotion)
1488 const FQuat OldRotationQuat = UpdatedComponent->GetComponentQuat();
1489 const FVector OldLocation = UpdatedComponent->GetComponentLocation();
1490 SimulateRootMotion(DeltaSeconds, RootMotionParams.GetRootMotionTransform());
1492#if !(UE_BUILD_SHIPPING)
1510 if (CharacterOwner && (CharacterOwner->RootMotionRepMoves.Num() > 0))
1512 CharacterOwner->SimulatedRootMotionPositionFixup(DeltaSeconds);
1515 else if (CurrentRootMotion.HasActiveRootMotionSources())
1518 bWasSimulatingRootMotion =
true;
1519 UE_LOG(LogRootMotion, Verbose, TEXT(
"UCharacterMovementComponent::SimulatedTick"));
1522 bool bCorrectedToServer =
false;
1523 const FVector OldLocation = UpdatedComponent->GetComponentLocation();
1524 const FQuat OldRotation = UpdatedComponent->GetComponentQuat();
1525 if (CharacterOwner->RootMotionRepMoves.Num() > 0)
1528 FSimulatedRootMotionReplicatedMove& RootMotionRepMove = CharacterOwner->RootMotionRepMoves.Last();
1529 if (CharacterOwner->RestoreReplicatedMove(RootMotionRepMove))
1531 bCorrectedToServer =
true;
1533 Acceleration = RootMotionRepMove.RootMotion.Acceleration;
1535 CharacterOwner->PostNetReceiveVelocity(RootMotionRepMove.RootMotion.LinearVelocity);
1536 LastUpdateVelocity = RootMotionRepMove.RootMotion.LinearVelocity;
1540 ConvertRootMotionServerIDsToLocalIDs(CurrentRootMotion, RootMotionRepMove.RootMotion.AuthoritativeRootMotion, RootMotionRepMove.Time);
1541 RootMotionRepMove.RootMotion.AuthoritativeRootMotion.CullInvalidSources();
1544 CurrentRootMotion.UpdateStateFrom(RootMotionRepMove.RootMotion.AuthoritativeRootMotion,
true);
1547 UE_LOG(LogRootMotion, Log, TEXT(
"\tClearing old moves in SimulatedTick (%d)"), CharacterOwner->RootMotionRepMoves.Num());
1548 CharacterOwner->RootMotionRepMoves.Reset();
1555 if (bCorrectedToServer || CurrentRootMotion.NeedsSimulatedSmoothing())
1557 SmoothCorrection(OldLocation, OldRotation, UpdatedComponent->GetComponentLocation(), UpdatedComponent->GetComponentQuat());
1566 if (bWasSimulatingRootMotion)
1568 bWasSimulatingRootMotion =
false;
1569 CharacterOwner->RootMotionRepMoves.Empty();
1570 CharacterOwner->OnRep_ReplicatedMovement();
1571 CharacterOwner->OnRep_ReplicatedBasedMovement();
1575 if (CharacterOwner->IsReplicatingMovement() && UpdatedComponent)
1580 const bool bPreventMeshMovement = !bNetworkSmoothingComplete;
1583 if(NetworkSmoothingMode != ENetworkSmoothingMode::Disabled)
1587 if (CharacterOwner->IsMatineeControlled() || CharacterOwner->IsPlayingRootMotion())
1595 SimulateMovement(DeltaSeconds);
1600 if (CharacterOwner->IsMatineeControlled() || CharacterOwner->IsPlayingRootMotion())
1606 SimulateMovement(DeltaSeconds);
1628 if (!bNetworkSmoothingComplete)
1630 QUICK_SCOPE_CYCLE_COUNTER(STAT_Character_CharacterMovementSmoothClientPosition);
1635 UE_LOG(LogVRBaseCharacterMovement, Verbose, TEXT(
"Skipping network smoothing for %s."), *GetNameSafe(CharacterOwner));
1640 float ClientTimeStamp,
1642 uint8 CompressedFlags,
1643 const FVector& NewAccel
1646 if (!HasValidData())
1652 CharacterOwner->CheckJumpInput(DeltaTime);
1654 Acceleration = ConstrainInputAcceleration(NewAccel);
1655 Acceleration = Acceleration.GetClampedToMaxSize(GetMaxAcceleration());
1656 AnalogInputModifier = ComputeAnalogInputModifier();
1658 FVector OldLocation = UpdatedComponent->GetComponentLocation();
1659 FQuat OldRotation = UpdatedComponent->GetComponentQuat();
1667 const bool bWasPlayingRootMotion = CharacterOwner->IsPlayingRootMotion();
1672 if (!HasValidData())
1678 if (CharacterOwner && !CharacterOwner->bClientUpdating && !CharacterOwner->IsPlayingRootMotion() && CharacterOwner->GetMesh())
1680 if (!bWasPlayingRootMotion)
1682 TickCharacterPose(DeltaTime);
1687 CharacterOwner->GetMesh()->ConditionallyDispatchQueuedAnimEvents();
1690 if (CharacterOwner && UpdatedComponent)
1693 static const auto CVarNetEnableListenServerSmoothing = IConsoleManager::Get().FindConsoleVariable(TEXT(
"p.NetEnableListenServerSmoothing"));
1694 if (CVarNetEnableListenServerSmoothing->GetInt() &&
1695 CharacterOwner->GetRemoteRole() == ROLE_AutonomousProxy &&
1696 IsNetMode(NM_ListenServer))
1698 SmoothCorrection(OldLocation, OldRotation, UpdatedComponent->GetComponentLocation(), UpdatedComponent->GetComponentQuat());
1707 if (!HasValidData())
1713 Super::SmoothCorrection(OldLocation, OldRotation, NewLocation, NewRotation);
1716 checkSlow(GetNetMode() != NM_DedicatedServer);
1717 checkSlow(GetNetMode() != NM_Standalone);
1720 const bool bIsSimulatedProxy = (CharacterOwner->GetLocalRole() == ROLE_SimulatedProxy);
1721 const bool bIsRemoteAutoProxy = (CharacterOwner->GetRemoteRole() == ROLE_AutonomousProxy);
1722 ensure(bIsSimulatedProxy || bIsRemoteAutoProxy);
1725 bNetworkSmoothingComplete =
false;
1728 if (NetworkSmoothingMode == ENetworkSmoothingMode::Replay)
1733 else if (NetworkSmoothingMode == ENetworkSmoothingMode::Disabled)
1735 UpdatedComponent->SetWorldLocationAndRotation(NewLocation, NewRotation,
false,
nullptr, ETeleportType::TeleportPhysics);
1736 bNetworkSmoothingComplete =
true;
1740 const UWorld* MyWorld = GetWorld();
1741 if (!ensure(MyWorld !=
nullptr))
1747 FVector OldWorldLocation = OldLocation;
1748 FQuat OldWorldRotation = OldRotation;
1749 FVector NewWorldLocation = NewLocation;
1750 FQuat NewWorldRotation = NewRotation;
1754 if (GetNetMode() < ENetMode::NM_Client)
1761 FTransform NewWorldTransform(NewRotation, NewLocation, UpdatedComponent->GetRelativeScale3D());
1763 FTransform NewWorld = CurrentRelative * NewWorldTransform;
1766 NewWorldLocation = NewWorld.GetLocation();
1767 NewWorldRotation = NewWorld.GetRotation();
1772 FVector NewToOldVector = (OldWorldLocation - NewWorldLocation);
1773 if (bIsNavWalkingOnServer && FMath::Abs(NewToOldVector.Z) < NavWalkingFloorDistTolerance)
1778 NewToOldVector.Z = 0;
1781 const float DistSq = NewToOldVector.SizeSquared();
1782 if (DistSq > FMath::Square(ClientData->MaxSmoothNetUpdateDist))
1784 ClientData->MeshTranslationOffset = (DistSq > FMath::Square(ClientData->NoSmoothNetUpdateDist))
1785 ? FVector::ZeroVector
1786 : ClientData->MeshTranslationOffset + ClientData->MaxSmoothNetUpdateDist * NewToOldVector.GetSafeNormal();
1790 ClientData->MeshTranslationOffset = ClientData->MeshTranslationOffset + NewToOldVector;
1793 UE_LOG(LogVRBaseCharacterMovement, Verbose, TEXT(
"Proxy %s SmoothCorrection(%.2f)"), *GetNameSafe(CharacterOwner), FMath::Sqrt(DistSq));
1794 if (NetworkSmoothingMode == ENetworkSmoothingMode::Linear)
1798 if ((!OldRotation.Equals(NewRotation, 1e-5f)))
1801 UpdatedComponent->SetWorldLocationAndRotation(NewLocation, NewRotation,
false,
nullptr, GetTeleportType());
1802 ClientData->MeshTranslationOffset = FVector::ZeroVector;
1803 ClientData->MeshRotationOffset = ClientData->MeshRotationTarget;
1804 bNetworkSmoothingComplete =
true;
1808 ClientData->OriginalMeshTranslationOffset = ClientData->MeshTranslationOffset;
1811 ClientData->OriginalMeshRotationOffset = OldRotation;
1812 ClientData->MeshRotationOffset = OldRotation;
1813 ClientData->MeshRotationTarget = NewRotation;
1817 if (NewLocation != OldLocation)
1820 UpdatedComponent->SetWorldLocation(NewLocation,
false,
nullptr, GetTeleportType());
1840 ClientData->MeshRotationOffset = FQuat::Identity;
1841 ClientData->MeshRotationTarget = FQuat::Identity;
1844 UpdatedComponent->SetWorldLocationAndRotation(NewLocation, NewRotation,
false,
nullptr, GetTeleportType());
1852 if (ClientData->SmoothingClientTimeStamp > ClientData->SmoothingServerTimeStamp)
1854 const double OldClientTimeStamp = ClientData->SmoothingClientTimeStamp;
1855 ClientData->SmoothingClientTimeStamp = FMath::LerpStable(ClientData->SmoothingServerTimeStamp, OldClientTimeStamp, 0.5);
1857 UE_LOG(LogVRBaseCharacterMovement, VeryVerbose, TEXT(
"SmoothCorrection: Pull back client from ClientTimeStamp: %.6f to %.6f, ServerTimeStamp: %.6f for %s"),
1858 OldClientTimeStamp, ClientData->SmoothingClientTimeStamp, ClientData->SmoothingServerTimeStamp, *GetNameSafe(CharacterOwner));
1862 double OldServerTimeStamp = ClientData->SmoothingServerTimeStamp;
1864 if (bIsSimulatedProxy)
1867 ServerLastTransformUpdateTimeStamp = CharacterOwner->GetReplicatedServerLastTransformUpdateTimeStamp();
1869 ClientData->SmoothingServerTimeStamp = ServerLastTransformUpdateTimeStamp;
1872 if (ClientData->LastCorrectionTime == 0)
1874 ClientData->SmoothingClientTimeStamp = ClientData->SmoothingServerTimeStamp;
1875 OldServerTimeStamp = ClientData->SmoothingServerTimeStamp;
1879 const double ServerDeltaTime = ClientData->SmoothingServerTimeStamp - OldServerTimeStamp;
1880 const double MaxOffset = ClientData->MaxClientSmoothingDeltaTime;
1881 const double MinOffset = FMath::Min(
double(ClientData->SmoothNetUpdateTime), MaxOffset);
1884 const double MaxDelta = FMath::Clamp(ServerDeltaTime * 1.25, MinOffset, MaxOffset);
1885 ClientData->SmoothingClientTimeStamp = FMath::Clamp(ClientData->SmoothingClientTimeStamp, ClientData->SmoothingServerTimeStamp - MaxDelta, ClientData->SmoothingServerTimeStamp);
1888 ClientData->LastCorrectionDelta = ClientData->SmoothingServerTimeStamp - ClientData->SmoothingClientTimeStamp;
1889 ClientData->LastCorrectionTime = MyWorld->GetTimeSeconds();
1891 UE_LOG(LogVRBaseCharacterMovement, VeryVerbose, TEXT(
"SmoothCorrection: WorldTime: %.6f, ServerTimeStamp: %.6f, ClientTimeStamp: %.6f, Delta: %.6f for %s"),
1892 MyWorld->GetTimeSeconds(), ClientData->SmoothingServerTimeStamp, ClientData->SmoothingClientTimeStamp, ClientData->LastCorrectionDelta, *GetNameSafe(CharacterOwner));
1901 if (!HasValidData() || NetworkSmoothingMode == ENetworkSmoothingMode::Disabled)
1907 checkSlow(GetNetMode() != NM_DedicatedServer);
1908 checkSlow(GetNetMode() != NM_Standalone);
1911 const bool bIsSimulatedProxy = (CharacterOwner->GetLocalRole() == ROLE_SimulatedProxy);
1912 const bool bIsRemoteAutoProxy = (CharacterOwner->GetRemoteRole() == ROLE_AutonomousProxy);
1913 if (!ensure(bIsSimulatedProxy || bIsRemoteAutoProxy))
1918 SmoothClientPosition_Interpolate(DeltaSeconds);
1934 if (NetworkSmoothingMode == ENetworkSmoothingMode::Linear)
1937 const FVector NewRelLocation = ClientData->MeshRotationOffset.UnrotateVector(ClientData->MeshTranslationOffset);
1940 else if (NetworkSmoothingMode == ENetworkSmoothingMode::Exponential)
1943 const FVector NewRelTranslation = UpdatedComponent->GetComponentToWorld().InverseTransformVectorNoScale(ClientData->MeshTranslationOffset);
1944 const FQuat NewRelRotation = ClientData->MeshRotationOffset;
1950 else if (NetworkSmoothingMode == ENetworkSmoothingMode::Replay)
1952 if (!UpdatedComponent->GetComponentQuat().Equals(ClientData->MeshRotationOffset, SCENECOMPONENT_QUAT_TOLERANCE))
1955 UpdatedComponent->SetWorldLocationAndRotation(ClientData->MeshTranslationOffset, ClientData->MeshRotationOffset);
1967 bHasRequestedVelocity = bNewHasRequestedVelocity;
1994 Super::UpdateFromCompressedFlags(Flags);
2000 InMovement.X = FMath::RoundToFloat(InMovement.X * 100.f) / 100.f;
2001 InMovement.Y = FMath::RoundToFloat(InMovement.Y * 100.f) / 100.f;
2002 InMovement.Z = FMath::RoundToFloat(InMovement.Z * 100.f) / 100.f;
EVRMoveActionVelocityRetention
UENUM(Blueprintable)
@ VRMOVEACTION_Velocity_Clear
@ VRMOVEACTION_Velocity_Turn
@ VRMOVEACTION_Velocity_None
EVRMoveActionDataReq
UENUM(Blueprintable)
EVRMoveAction
UENUM(Blueprintable)
@ VRMOVEACTION_StopAllMovement
@ VRMOVEACTION_PauseTracking
@ VRMOVEACTION_SetRotation
EVRCustomMovementMode
UENUM(BlueprintType)
EVRConjoinedMovementModes
UENUM(BlueprintType)
DEFINE_LOG_CATEGORY(LogVRBaseCharacterMovement)
FVRPlayerNetworkCorrectedSignature OnCharacterNetworkCorrected_Bind
UPROPERTY(BlueprintAssignable, Category = "VRMovement")
USceneComponent * NetSmoother
UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess ...
UGripMotionControllerComponent * RightMotionController
UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess ...
FVRPlayerTeleportedSignature OnCharacterTeleported_Bind
UPROPERTY(BlueprintAssignable, Category = "VRMovement")
FTransform OffsetComponentToWorld
UPROPERTY(BlueprintReadOnly, Transient, Category = "VRExpansionLibrary")
void UpdateClimbingMovement(float DeltaTime)
UFUNCTION(BlueprintNativeEvent, meta = (DisplayName = "UpdateClimbingMovement", ScriptName = "UpdateC...
UReplicatedVRCameraComponent * VRReplicatedCamera
UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess ...
UGripMotionControllerComponent * LeftMotionController
UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess ...
UParentRelativeAttachmentComponent * ParentRelativeAttachment
UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess ...
AVRPlayerController * OwningVRPlayerController
UPROPERTY(Transient, DuplicateTransient)
FRotator LastRotationInput
void TeleportMoveGrips(bool bTeleportPhysicsGrips=true, bool bIsForPostTeleport=false)
UFUNCTION(BlueprintCallable, Category = "GripMotionController")
UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent), ClassGroup = VRExpansionLibrary)
void UpdateTracking(float DeltaTime)
bool bUpdateInCharacterMovement
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRExpansionLibrary")
UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent), ClassGroup = VRExpansionLibrary)
void UpdateTracking(float DeltaTime)
float VRClimbingStepUpMaxSize
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement|Climbing")
void SetHasRequestedVelocity(bool bNewHasRequestedVelocity)
void PerformMoveAction_Custom(EVRMoveAction MoveActionToPerform, EVRMoveActionDataReq DataRequirementsForMoveAction, FVector MoveActionVector, FRotator MoveActionRotator, uint8 MoveActionFlags=0)
UFUNCTION(BlueprintCallable, Category = "VRMovement")
void PerformMoveAction_SetTrackingPaused(bool bNewTrackingPaused)
UFUNCTION(BlueprintCallable, Category = "VRMovement")
float VRClimbingEdgeRejectDistance
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement|Climbing")
virtual bool VRClimbStepUp(const FVector &GravDir, const FVector &Delta, const FHitResult &InHit, FStepDownResult *OutStepDownResult=nullptr)
virtual bool DoMASnapTurn(FVRMoveActionContainer &MoveAction)
float VRClimbingStepUpMultiplier
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement|Climbing")
virtual bool VerifyClientTimeStamp(float TimeStamp, FNetworkPredictionData_Server_Character &ServerData) override
virtual void PerformMovement(float DeltaSeconds) override
float VRLowGravWallFrictionScaler
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement|LowGrav", meta = (ClampMin = "0....
void OnMovementModeChanged(EMovementMode PreviousMovementMode, uint8 PreviousCustomMode) override
void StartPushBackNotification(FHitResult HitResult)
void RestorePreAdditiveVRMotionVelocity()
virtual void PhysCustom(float deltaTime, int32 Iterations) override
virtual bool ForcePositionUpdate(float DeltaTime) override
FVector RewindVRMovement()
UFUNCTION(BlueprintCallable, Category = "VRMovement")
FVector GetActorFeetLocationVR() const
virtual void OnClientCorrectionReceived(class FNetworkPredictionData_Client_Character &ClientData, float TimeStamp, FVector NewLocation, FVector NewVelocity, UPrimitiveComponent *NewBase, FName NewBaseBoneName, bool bHasBase, bool bBaseRelativePosition, uint8 ServerMovementMode) override
virtual void PhysCustom_Climbing(float deltaTime, int32 Iterations)
virtual void StoreSetTrackingPaused(bool bNewTrackingPaused)
FVector AdditionalVRInputVector
virtual void SetUpdatedComponent(USceneComponent *NewUpdatedComponent)
FVRMoveActionArray MoveActionArray
virtual void PhysCustom_LowGrav(float deltaTime, int32 Iterations)
virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override
void SetClimbingMode(bool bIsClimbing)
UFUNCTION(BlueprintCallable, Category = "VRMovement|Climbing")
virtual float SlideAlongSurface(const FVector &Delta, float Time, const FVector &Normal, FHitResult &Hit, bool bHandleImpact) override
bool bCapHMDMovementToMaxMovementSpeed
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement")
FVROnPerformClimbingStepUp OnPerformClimbingStepUp
UPROPERTY(BlueprintAssignable, Category = "VRMovement")
float VRClimbingStepHeight
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement|Climbing")
virtual void SmoothClientPosition(float DeltaSeconds) override
void PerformMoveAction_SnapTurn(float SnapTurnDeltaYaw, EVRMoveActionVelocityRetention VelocityRetention=EVRMoveActionVelocityRetention::VRMOVEACTION_Velocity_None, bool bFlagGripTeleport=false, bool bFlagCharacterTeleport=false)
UFUNCTION(BlueprintCallable, Category = "VRMovement")
FVector RoundDirectMovement(FVector InMovement) const
void SetCrouchedHalfHeight(float NewCrouchedHalfHeight)
UFUNCTION(BlueprintCallable, Category = "VRMovement")
bool SetDefaultPostClimbMovementOnStepUp
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement|Climbing")
void PerformMoveAction_Teleport(FVector TeleportLocation, FRotator TeleportRotation, EVRMoveActionVelocityRetention VelocityRetention=EVRMoveActionVelocityRetention::VRMOVEACTION_Velocity_None, bool bSkipEncroachmentCheck=false)
UFUNCTION(BlueprintCallable, Category = "VRMovement")
virtual void ComputeFloorDist(const FVector &CapsuleLocation, float LineDistance, float SweepDistance, FFindFloorResult &OutFloorResult, float SweepRadius, const FHitResult *DownwardSweepResult=NULL) const override
bool bIgnoreSimulatingComponentsInFloorCheck
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement")
virtual void MoveAutonomous(float ClientTimeStamp, float DeltaTime, uint8 CompressedFlags, const FVector &NewAccel) override
UVRBaseCharacterMovementComponent(const FObjectInitializer &ObjectInitializer=FObjectInitializer::Get())
FVRCharacterNetworkMoveDataContainer VRNetworkMoveDataContainer
EVRConjoinedMovementModes VRReplicatedMovementMode
virtual bool DoMAPauseTracking(FVRMoveActionContainer &MoveAction)
FVRCharacterMoveResponseDataContainer VRMoveResponseDataContainer
AVRBaseCharacter * BaseVRCharacterOwner
UPROPERTY(Transient, DuplicateTransient)
virtual void SimulatedTick(float DeltaSeconds) override
EVRConjoinedMovementModes GetReplicatedMovementMode()
UFUNCTION(BlueprintPure, Category = "VRMovement")
bool bHoldPositionOnTrackingLossThresholdHit
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement")
virtual bool DoMAStopAllMovement(FVRMoveActionContainer &MoveAction)
EVRConjoinedMovementModes DefaultPostClimbMovement
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement|Climbing")
bool bApplyAdditionalVRInputVectorAsNegative
FORCEINLINE void ApplyReplicatedMovementMode(EVRConjoinedMovementModes &NewMovementMode, bool bClearMovementMode=false)
void AddCustomReplicatedMovement(FVector Movement)
UFUNCTION(BlueprintCallable, Category = "BaseVRCharacterMovementComponent|VRLocations")
virtual void OnMoveCompleted(FAIRequestID RequestID, const FPathFollowingResult &Result)
float VRWallSlideScaler
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement", meta = (ClampMin = "0....
bool bUseClientControlRotation
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRBaseCharacterMovementComponent")
bool bDisableSimulatedTickWhenSmoothingMovement
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRBaseCharacterMovementComponent|Smoothing")
bool VRLowGravIgnoresDefaultFluidFriction
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement|LowGrav")
bool CheckForMoveAction()
void UpdateFromCompressedFlags(uint8 Flags) override
void CheckServerAuthedMoveAction()
FVector GetCustomInputVector()
UFUNCTION(BlueprintCallable, Category = "VRMovement")
float VREdgeRejectDistance
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement")
virtual void SmoothCorrection(const FVector &OldLocation, const FQuat &OldRotation, const FVector &NewLocation, const FQuat &NewRotation) override
void SetReplicatedMovementMode(EVRConjoinedMovementModes NewMovementMode)
UFUNCTION(BlueprintCallable, Category = "VRMovement")
FVector CustomVRInputVector
void RewindVRRelativeMovement()
bool bRunControlRotationInMovementComponent
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement")
bool bClampClimbingStepUp
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement|Climbing")
float VRClimbingMaxReleaseVelocitySize
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement|Climbing")
void EndPushBackNotification()
void PerformMoveAction_StopAllMovement()
UFUNCTION(BlueprintCallable, Category = "VRMovement")
float TrackingLossThreshold
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement", meta = (ClampMin = "0....
void SmoothClientPosition_UpdateVRVisuals()
virtual bool DoMATeleport(FVRMoveActionContainer &MoveAction)
void PerformMoveAction_SetRotation(float NewYaw, EVRMoveActionVelocityRetention VelocityRetention=EVRMoveActionVelocityRetention::VRMOVEACTION_Velocity_None, bool bFlagGripTeleport=false, bool bFlagCharacterTeleport=false)
UFUNCTION(BlueprintCallable, Category = "VRMovement")
virtual bool DoMASetRotation(FVRMoveActionContainer &MoveAction)
void ApplyVRMotionToVelocity(float deltaTime)
void ClearCustomReplicatedMovement()
UFUNCTION(BlueprintCallable, Category = "BaseVRCharacterMovementComponent|VRLocations")
virtual void ApplyNetworkMovementMode(const uint8 ReceivedMode) override
UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent), ClassGroup = VRExpansionLibrary)
TArray< FVRMoveActionContainer > MoveActions
UPROPERTY()
FVector MoveActionLoc
UPROPERTY()
EVRMoveActionVelocityRetention VelRetentionSetting
UPROPERTY()
EVRMoveActionDataReq MoveActionDataReq
UPROPERTY()
uint8 MoveActionFlags
UPROPERTY()
EVRMoveAction MoveAction
UPROPERTY()
FVector MoveActionVel
UPROPERTY()
FRotator MoveActionRot
UPROPERTY()