Update VRE, Fix broken Asset

This commit is contained in:
Simeon "Waldo" Wallrath 2025-01-27 18:51:40 +01:00
parent 9eeb6901d4
commit d0229c6c2c
9 changed files with 97 additions and 356 deletions

View file

@ -8334,12 +8334,12 @@ void UGripMotionControllerComponent::GetHandType(EControllerHand& Hand)
{
// Check if the palm motion source extension is being used
// I assume eventually epic will handle this case
if (MotionSource.Compare(FName(TEXT("RightPalm"))) == 0)
if (MotionSource.Compare(FName(TEXT("RightPalm"))) == 0 || MotionSource.Compare(FName(TEXT("RightWrist"))) == 0)
{
Hand = EControllerHand::Right;
}
// Could skip this and default to left now but would rather check
else if (MotionSource.Compare(FName(TEXT("LeftPalm"))) == 0)
else if (MotionSource.Compare(FName(TEXT("LeftPalm"))) == 0 || MotionSource.Compare(FName(TEXT("LeftWrist"))) == 0)
{
Hand = EControllerHand::Left;
}

View file

@ -129,96 +129,23 @@ void AGrippableActor::PreReplication(IRepChangedPropertyTracker & ChangedPropert
void AGrippableActor::GatherCurrentMovement()
{
if (IsReplicatingMovement() || (RootComponent && RootComponent->GetAttachParent()))
Super::GatherCurrentMovement();
FRepMovement RepMovement = GetReplicatedMovement();
if (RootComponent && (!RepMovement.bRepPhysics || RootComponent->GetAttachParent()))
{
bool bWasAttachmentModified = false;
bool bWasRepMovementModified = false;
AActor* OldAttachParent = AttachmentWeldReplication.AttachParent;
USceneComponent* OldAttachComponent = AttachmentWeldReplication.AttachComponent;
AttachmentWeldReplication.AttachParent = nullptr;
AttachmentWeldReplication.AttachComponent = nullptr;
FRepMovement& RepMovement = GetReplicatedMovement_Mutable();
UPrimitiveComponent* RootPrimComp = Cast<UPrimitiveComponent>(GetRootComponent());
if (RootPrimComp && RootPrimComp->IsSimulatingPhysics())
if (!RepMovement.bRepPhysics || (!RootPrimComp || !RootPrimComp->IsSimulatingPhysics()))
{
#if UE_WITH_IRIS
const bool bPrevRepPhysics = GetReplicatedMovement_Mutable().bRepPhysics;
#endif // UE_WITH_IRIS
bool bWasAttachmentModified = false;
bool bFoundInCache = false;
AActor* OldAttachParent = AttachmentWeldReplication.AttachParent;
USceneComponent* OldAttachComponent = AttachmentWeldReplication.AttachComponent;
UWorld* World = GetWorld();
AttachmentWeldReplication.AttachParent = nullptr;
AttachmentWeldReplication.AttachComponent = nullptr;
const bool bShouldUsePhysicsReplicationCache = GetPhysicsReplicationMode() != EPhysicsReplicationMode::Default;
int ServerFrame = 0;
if (bShouldUsePhysicsReplicationCache)
{
if (FPhysScene_Chaos* Scene = static_cast<FPhysScene_Chaos*>(World->GetPhysicsScene()))
{
if (const FRigidBodyState* FoundState = Scene->GetStateFromReplicationCache(RootPrimComp, /*OUT*/ServerFrame))
{
if (RepMovement.ServerFrame != ServerFrame)
{
RepMovement.FillFrom(*FoundState, this, ServerFrame);
bWasRepMovementModified = true;
}
bFoundInCache = true;
}
}
}
if (!bFoundInCache)
{
// fallback to GT data
FRigidBodyState RBState;
RootPrimComp->GetRigidBodyState(RBState);
RepMovement.FillFrom(RBState, this, 0);
}
// Don't replicate movement if we're welded to another parent actor.
// Their replication will affect our position indirectly since we are attached.
RepMovement.bRepPhysics = !RootPrimComp->IsWelded();
if (!RepMovement.bRepPhysics)
{
if (RootComponent->GetAttachParent() != nullptr)
{
// Networking for attachments assumes the RootComponent of the AttachParent actor.
// If that's not the case, we can't update this, as the client wouldn't be able to resolve the Component and would detach as a result.
AttachmentWeldReplication.AttachParent = RootComponent->GetAttachParent()->GetAttachmentRootActor();
if (AttachmentWeldReplication.AttachParent != nullptr)
{
AttachmentWeldReplication.LocationOffset = RootComponent->GetRelativeLocation();
AttachmentWeldReplication.RotationOffset = RootComponent->GetRelativeRotation();
AttachmentWeldReplication.RelativeScale3D = RootComponent->GetRelativeScale3D();
AttachmentWeldReplication.AttachComponent = RootComponent->GetAttachParent();
AttachmentWeldReplication.AttachSocket = RootComponent->GetAttachSocketName();
AttachmentWeldReplication.bIsWelded = RootPrimComp ? RootPrimComp->IsWelded() : false;
// Technically, the values might have stayed the same, but we'll just assume they've changed.
bWasAttachmentModified = true;
}
}
}
// Technically, the values might have stayed the same, but we'll just assume they've changed.
bWasRepMovementModified = true;
#if UE_WITH_IRIS
// If RepPhysics has changed value then notify the ReplicationSystem
if (bPrevRepPhysics != GetReplicatedMovement_Mutable().bRepPhysics)
{
UpdateReplicatePhysicsCondition();
}
#endif // UE_WITH_IRIS
}
else if (RootComponent != nullptr)
{
// If we are attached, don't replicate absolute position, use AttachmentReplication instead.
if (RootComponent->GetAttachParent() != nullptr)
{
@ -238,34 +165,16 @@ void AGrippableActor::GatherCurrentMovement()
bWasAttachmentModified = true;
}
}
else
if (bWasAttachmentModified ||
OldAttachParent != AttachmentWeldReplication.AttachParent ||
OldAttachComponent != AttachmentWeldReplication.AttachComponent)
{
RepMovement.Location = FRepMovement::RebaseOntoZeroOrigin(RootComponent->GetComponentLocation(), this);
RepMovement.Rotation = RootComponent->GetComponentRotation();
RepMovement.LinearVelocity = GetVelocity();
RepMovement.AngularVelocity = FVector::ZeroVector;
// Technically, the values might have stayed the same, but we'll just assume they've changed.
bWasRepMovementModified = true;
}
bWasRepMovementModified = (bWasRepMovementModified || RepMovement.bRepPhysics);
RepMovement.bRepPhysics = false;
}
#if WITH_PUSH_MODEL
if (bWasRepMovementModified)
{
MARK_PROPERTY_DIRTY_FROM_NAME(AActor, ReplicatedMovement, this);
}
if (bWasAttachmentModified ||
OldAttachParent != AttachmentWeldReplication.AttachParent ||
OldAttachComponent != AttachmentWeldReplication.AttachComponent)
{
MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableActor, AttachmentWeldReplication, this);
}
MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableActor, AttachmentWeldReplication, this);
#endif
}
}
}
}

View file

@ -233,96 +233,23 @@ void AGrippableSkeletalMeshActor::PreReplication(IRepChangedPropertyTracker& Cha
void AGrippableSkeletalMeshActor::GatherCurrentMovement()
{
if (IsReplicatingMovement() || (RootComponent && RootComponent->GetAttachParent()))
Super::GatherCurrentMovement();
FRepMovement RepMovement = GetReplicatedMovement();
if (RootComponent && (!RepMovement.bRepPhysics || RootComponent->GetAttachParent()))
{
bool bWasAttachmentModified = false;
bool bWasRepMovementModified = false;
AActor* OldAttachParent = AttachmentWeldReplication.AttachParent;
USceneComponent* OldAttachComponent = AttachmentWeldReplication.AttachComponent;
AttachmentWeldReplication.AttachParent = nullptr;
AttachmentWeldReplication.AttachComponent = nullptr;
FRepMovement& RepMovement = GetReplicatedMovement_Mutable();
UPrimitiveComponent* RootPrimComp = Cast<UPrimitiveComponent>(GetRootComponent());
if (RootPrimComp && RootPrimComp->IsSimulatingPhysics())
if (!RepMovement.bRepPhysics || (!RootPrimComp || !RootPrimComp->IsSimulatingPhysics()))
{
#if UE_WITH_IRIS
const bool bPrevRepPhysics = GetReplicatedMovement_Mutable().bRepPhysics;
#endif // UE_WITH_IRIS
bool bWasAttachmentModified = false;
bool bFoundInCache = false;
AActor* OldAttachParent = AttachmentWeldReplication.AttachParent;
USceneComponent* OldAttachComponent = AttachmentWeldReplication.AttachComponent;
UWorld* World = GetWorld();
AttachmentWeldReplication.AttachParent = nullptr;
AttachmentWeldReplication.AttachComponent = nullptr;
const bool bShouldUsePhysicsReplicationCache = GetPhysicsReplicationMode() != EPhysicsReplicationMode::Default;
int ServerFrame = 0;
if (bShouldUsePhysicsReplicationCache)
{
if (FPhysScene_Chaos* Scene = static_cast<FPhysScene_Chaos*>(World->GetPhysicsScene()))
{
if (const FRigidBodyState* FoundState = Scene->GetStateFromReplicationCache(RootPrimComp, /*OUT*/ServerFrame))
{
if (RepMovement.ServerFrame != ServerFrame)
{
RepMovement.FillFrom(*FoundState, this, ServerFrame);
bWasRepMovementModified = true;
}
bFoundInCache = true;
}
}
}
if (!bFoundInCache)
{
// fallback to GT data
FRigidBodyState RBState;
RootPrimComp->GetRigidBodyState(RBState);
RepMovement.FillFrom(RBState, this, 0);
}
// Don't replicate movement if we're welded to another parent actor.
// Their replication will affect our position indirectly since we are attached.
RepMovement.bRepPhysics = !RootPrimComp->IsWelded();
if (!RepMovement.bRepPhysics)
{
if (RootComponent->GetAttachParent() != nullptr)
{
// Networking for attachments assumes the RootComponent of the AttachParent actor.
// If that's not the case, we can't update this, as the client wouldn't be able to resolve the Component and would detach as a result.
AttachmentWeldReplication.AttachParent = RootComponent->GetAttachParent()->GetAttachmentRootActor();
if (AttachmentWeldReplication.AttachParent != nullptr)
{
AttachmentWeldReplication.LocationOffset = RootComponent->GetRelativeLocation();
AttachmentWeldReplication.RotationOffset = RootComponent->GetRelativeRotation();
AttachmentWeldReplication.RelativeScale3D = RootComponent->GetRelativeScale3D();
AttachmentWeldReplication.AttachComponent = RootComponent->GetAttachParent();
AttachmentWeldReplication.AttachSocket = RootComponent->GetAttachSocketName();
AttachmentWeldReplication.bIsWelded = RootPrimComp ? RootPrimComp->IsWelded() : false;
// Technically, the values might have stayed the same, but we'll just assume they've changed.
bWasAttachmentModified = true;
#if UE_WITH_IRIS
// If RepPhysics has changed value then notify the ReplicationSystem
if (bPrevRepPhysics != GetReplicatedMovement_Mutable().bRepPhysics)
{
UpdateReplicatePhysicsCondition();
}
#endif // UE_WITH_IRIS
}
}
}
// Technically, the values might have stayed the same, but we'll just assume they've changed.
bWasRepMovementModified = true;
}
else if (RootComponent != nullptr)
{
// If we are attached, don't replicate absolute position, use AttachmentReplication instead.
if (RootComponent->GetAttachParent() != nullptr)
{
@ -342,33 +269,16 @@ void AGrippableSkeletalMeshActor::GatherCurrentMovement()
bWasAttachmentModified = true;
}
}
else
if (bWasAttachmentModified ||
OldAttachParent != AttachmentWeldReplication.AttachParent ||
OldAttachComponent != AttachmentWeldReplication.AttachComponent)
{
RepMovement.Location = FRepMovement::RebaseOntoZeroOrigin(RootComponent->GetComponentLocation(), this);
RepMovement.Rotation = RootComponent->GetComponentRotation();
RepMovement.LinearVelocity = GetVelocity();
RepMovement.AngularVelocity = FVector::ZeroVector;
// Technically, the values might have stayed the same, but we'll just assume they've changed.
bWasRepMovementModified = true;
}
bWasRepMovementModified = (bWasRepMovementModified || RepMovement.bRepPhysics);
RepMovement.bRepPhysics = false;
}
#if WITH_PUSH_MODEL
if (bWasRepMovementModified)
{
MARK_PROPERTY_DIRTY_FROM_NAME(AActor, ReplicatedMovement, this);
}
if (bWasAttachmentModified ||
OldAttachParent != AttachmentWeldReplication.AttachParent ||
OldAttachComponent != AttachmentWeldReplication.AttachComponent)
{
MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableSkeletalMeshActor, AttachmentWeldReplication, this);
}
MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableSkeletalMeshActor, AttachmentWeldReplication, this);
#endif
}
}
}
}

View file

@ -180,96 +180,23 @@ void AGrippableStaticMeshActor::PreReplication(IRepChangedPropertyTracker & Chan
void AGrippableStaticMeshActor::GatherCurrentMovement()
{
if (IsReplicatingMovement() || (RootComponent && RootComponent->GetAttachParent()))
Super::GatherCurrentMovement();
FRepMovement RepMovement = GetReplicatedMovement();
if (RootComponent && (!RepMovement.bRepPhysics || RootComponent->GetAttachParent()))
{
bool bWasAttachmentModified = false;
bool bWasRepMovementModified = false;
AActor* OldAttachParent = AttachmentWeldReplication.AttachParent;
USceneComponent* OldAttachComponent = AttachmentWeldReplication.AttachComponent;
AttachmentWeldReplication.AttachParent = nullptr;
AttachmentWeldReplication.AttachComponent = nullptr;
FRepMovement& RepMovement = GetReplicatedMovement_Mutable();
UPrimitiveComponent* RootPrimComp = Cast<UPrimitiveComponent>(GetRootComponent());
if (RootPrimComp && RootPrimComp->IsSimulatingPhysics())
if (!RepMovement.bRepPhysics || (!RootPrimComp || !RootPrimComp->IsSimulatingPhysics()))
{
#if UE_WITH_IRIS
const bool bPrevRepPhysics = GetReplicatedMovement_Mutable().bRepPhysics;
#endif // UE_WITH_IRIS
bool bWasAttachmentModified = false;
bool bFoundInCache = false;
AActor* OldAttachParent = AttachmentWeldReplication.AttachParent;
USceneComponent* OldAttachComponent = AttachmentWeldReplication.AttachComponent;
UWorld* World = GetWorld();
AttachmentWeldReplication.AttachParent = nullptr;
AttachmentWeldReplication.AttachComponent = nullptr;
const bool bShouldUsePhysicsReplicationCache = GetPhysicsReplicationMode() != EPhysicsReplicationMode::Default;
int ServerFrame = 0;
if (bShouldUsePhysicsReplicationCache)
{
if (FPhysScene_Chaos* Scene = static_cast<FPhysScene_Chaos*>(World->GetPhysicsScene()))
{
if (const FRigidBodyState* FoundState = Scene->GetStateFromReplicationCache(RootPrimComp, /*OUT*/ServerFrame))
{
if (RepMovement.ServerFrame != ServerFrame)
{
RepMovement.FillFrom(*FoundState, this, ServerFrame);
bWasRepMovementModified = true;
}
bFoundInCache = true;
}
}
}
if (!bFoundInCache)
{
// fallback to GT data
FRigidBodyState RBState;
RootPrimComp->GetRigidBodyState(RBState);
RepMovement.FillFrom(RBState, this, 0);
}
// Don't replicate movement if we're welded to another parent actor.
// Their replication will affect our position indirectly since we are attached.
RepMovement.bRepPhysics = !RootPrimComp->IsWelded();
if (!RepMovement.bRepPhysics)
{
if (RootComponent->GetAttachParent() != nullptr)
{
// Networking for attachments assumes the RootComponent of the AttachParent actor.
// If that's not the case, we can't update this, as the client wouldn't be able to resolve the Component and would detach as a result.
AttachmentWeldReplication.AttachParent = RootComponent->GetAttachParent()->GetAttachmentRootActor();
if (AttachmentWeldReplication.AttachParent != nullptr)
{
AttachmentWeldReplication.LocationOffset = RootComponent->GetRelativeLocation();
AttachmentWeldReplication.RotationOffset = RootComponent->GetRelativeRotation();
AttachmentWeldReplication.RelativeScale3D = RootComponent->GetRelativeScale3D();
AttachmentWeldReplication.AttachComponent = RootComponent->GetAttachParent();
AttachmentWeldReplication.AttachSocket = RootComponent->GetAttachSocketName();
AttachmentWeldReplication.bIsWelded = RootPrimComp ? RootPrimComp->IsWelded() : false;
// Technically, the values might have stayed the same, but we'll just assume they've changed.
bWasAttachmentModified = true;
#if UE_WITH_IRIS
// If RepPhysics has changed value then notify the ReplicationSystem
if (bPrevRepPhysics != GetReplicatedMovement_Mutable().bRepPhysics)
{
UpdateReplicatePhysicsCondition();
}
#endif // UE_WITH_IRIS
}
}
}
// Technically, the values might have stayed the same, but we'll just assume they've changed.
bWasRepMovementModified = true;
}
else if (RootComponent != nullptr)
{
// If we are attached, don't replicate absolute position, use AttachmentReplication instead.
if (RootComponent->GetAttachParent() != nullptr)
{
@ -289,33 +216,16 @@ void AGrippableStaticMeshActor::GatherCurrentMovement()
bWasAttachmentModified = true;
}
}
else
if (bWasAttachmentModified ||
OldAttachParent != AttachmentWeldReplication.AttachParent ||
OldAttachComponent != AttachmentWeldReplication.AttachComponent)
{
RepMovement.Location = FRepMovement::RebaseOntoZeroOrigin(RootComponent->GetComponentLocation(), this);
RepMovement.Rotation = RootComponent->GetComponentRotation();
RepMovement.LinearVelocity = GetVelocity();
RepMovement.AngularVelocity = FVector::ZeroVector;
// Technically, the values might have stayed the same, but we'll just assume they've changed.
bWasRepMovementModified = true;
}
bWasRepMovementModified = (bWasRepMovementModified || RepMovement.bRepPhysics);
RepMovement.bRepPhysics = false;
}
#if WITH_PUSH_MODEL
if (bWasRepMovementModified)
{
MARK_PROPERTY_DIRTY_FROM_NAME(AActor, ReplicatedMovement, this);
}
if (bWasAttachmentModified ||
OldAttachParent != AttachmentWeldReplication.AttachParent ||
OldAttachComponent != AttachmentWeldReplication.AttachComponent)
{
MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableStaticMeshActor, AttachmentWeldReplication, this);
}
MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableStaticMeshActor, AttachmentWeldReplication, this);
#endif
}
}
}
}

View file

@ -161,17 +161,14 @@ void UCollisionIgnoreSubsystem::CheckActiveFilters()
{
bool bMadeChanges = false;
for (TPair<FCollisionPrimPair, FCollisionIgnorePairArray>& KeyPair : CollisionTrackedPairs)
for (TMap<FCollisionPrimPair, FCollisionIgnorePairArray>::TIterator ItRemove = CollisionTrackedPairs.CreateIterator(); ItRemove; ++ItRemove)
{
// First check for invalid primitives
if (!IsValid(KeyPair.Key.Prim1) || !IsValid(KeyPair.Key.Prim2))
// First check for invalid primitives and an empty pair array
if (!IsValid(ItRemove->Key.Prim1) || !IsValid(ItRemove->Key.Prim2) || ItRemove->Value.PairArray.Num() < 1)
{
// If we don't have a map element for this pair, then add it now
if (!RemovedPairs.Contains(KeyPair.Key))
{
RemovedPairs.Add(KeyPair.Key, KeyPair.Value);
bMadeChanges = true;
}
ItRemove->Value.PairArray.Empty();
ItRemove.RemoveCurrent();
bMadeChanges = true;
continue; // skip remaining checks as we have invalid primitives anyway
}
@ -267,16 +264,6 @@ void UCollisionIgnoreSubsystem::CheckActiveFilters()
});
}
#endif
// If there are no pairs left
if (KeyPair.Value.PairArray.Num() < 1)
{
// Try and remove it, chaos should be cleaning up the ignore setups
if (!RemovedPairs.Contains(KeyPair.Key))
{
RemovedPairs.Add(KeyPair.Key, KeyPair.Value);
}
}
}
/*#if WITH_CHAOS
@ -295,13 +282,18 @@ void UCollisionIgnoreSubsystem::CheckActiveFilters()
}
#endif*/
for (const TPair<FCollisionPrimPair, FCollisionIgnorePairArray>& KeyPair : RemovedPairs)
/*for (const TPair<FCollisionPrimPair, FCollisionIgnorePairArray>& KeyPair : RemovedPairs)
{
if (CollisionTrackedPairs.Contains(KeyPair.Key))
{
CollisionTrackedPairs[KeyPair.Key].PairArray.Empty();
CollisionTrackedPairs.Remove(KeyPair.Key);
}
}*/
if (bMadeChanges)
{
CollisionTrackedPairs.Compact();
}
UpdateTimer(bMadeChanges);

View file

@ -468,7 +468,7 @@ void UVRRootComponent::UpdateCharacterCapsuleOffset()
{
if (owningVRChar && !owningVRChar->bRetainRoomscale && owningVRChar->NetSmoother)
{
if (!FMath::IsNearlyEqual(LastCapsuleHalfHeight, CapsuleHalfHeight))
if (bCenterCapsuleOnHMD || !FMath::IsNearlyEqual(LastCapsuleHalfHeight, CapsuleHalfHeight))
{
owningVRChar->NetSmoother->SetRelativeLocation(GetTargetHeightOffset(), false, nullptr, ETeleportType::TeleportPhysics);
@ -594,9 +594,23 @@ void UVRRootComponent::TickComponent(float DeltaTime, enum ELevelTick TickType,
Params.bFindInitialOverlaps = true;
bool bBlockingHit = false;
if (bUseWalkingCollisionOverride && bRetainRoomscale)
if (bUseWalkingCollisionOverride /* && bRetainRoomscale*/)
{
FVector TargetWorldLocation = OffsetComponentToWorld.GetLocation();
FVector TargetWorldLocation = FVector::ZeroVector;
if (bRetainRoomscale)
{
TargetWorldLocation = OffsetComponentToWorld.GetLocation();
}
else // Not Retained Roomscale
{
FVector NewLocation = StoredCameraRotOffset.RotateVector(FVector(VRCapsuleOffset.X, VRCapsuleOffset.Y, 0.0f)) + curCameraLoc;
FVector PlanerLocation = NewLocation - lastCameraLoc;
PlanerLocation.Z = 0.0f;
DifferenceFromLastFrame = GetComponentTransform().TransformVector(PlanerLocation);
TargetWorldLocation = LastPosition + DifferenceFromLastFrame;
}
bool bAllowWalkingCollision = false;
if (CharMove != nullptr)
{

View file

@ -137,8 +137,7 @@ public:
FQuat GetCalculatedRotation(FRotator InverseRot, float DeltaTime)
{
FRotator FinalRot = FRotator::ZeroRotator;
if (FPlatformMath::Abs(FRotator::ClampAxis(InverseRot.Yaw) - LastRot) < YawTolerance) // This is never true with the default value of 0.0f
if (FPlatformMath::Abs(FMath::FindDeltaAngleDegrees(InverseRot.Yaw, LastRot)) < YawTolerance) // This is never true with the default value of 0.0f
{
if (!bWasSetOnce)
{

View file

@ -57,7 +57,14 @@ public:
inline FVector GetTargetHeightOffset()
{
//return FVector::ZeroVector;
return FVector(0.f, 0.f, (-this->GetUnscaledCapsuleHalfHeight()) - VRCapsuleOffset.Z);
if (bCenterCapsuleOnHMD)
{
return FVector(0.f, 0.f, (-VRCapsuleOffset.Z) - curCameraLoc.Z);
}
else
{
return FVector(0.f, 0.f, (-this->GetUnscaledCapsuleHalfHeight()) - VRCapsuleOffset.Z);
}
}
/**
@ -266,7 +273,7 @@ void inline UVRRootComponent::GenerateOffsetToWorld(bool bUpdateBounds, bool bGe
if(owningVRChar && !owningVRChar->bRetainRoomscale)
{
OffsetComponentToWorld = FTransform(CamRotOffset.Quaternion(), FVector(0.0f, 0.0f, bCenterCapsuleOnHMD ? curCameraLoc.Z : 0.0f), FVector(1.0f)) * GetComponentTransform();
OffsetComponentToWorld = FTransform(CamRotOffset.Quaternion(), FVector(0.0f, 0.0f, 0.0f), FVector(1.0f)) * GetComponentTransform();
}
else
{