diff --git a/Source/RWTHVRToolkit/Private/Pawn/Navigation/CollisionHandlingMovement.cpp b/Source/RWTHVRToolkit/Private/Pawn/Navigation/CollisionHandlingMovement.cpp index 62bfa4602491506185646dfd769a3876ca4b8ccb..912fe0c1d74a99afb6a7ae6dfd9cd33a40771088 100644 --- a/Source/RWTHVRToolkit/Private/Pawn/Navigation/CollisionHandlingMovement.cpp +++ b/Source/RWTHVRToolkit/Private/Pawn/Navigation/CollisionHandlingMovement.cpp @@ -189,6 +189,9 @@ void UCollisionHandlingMovement::SetCapsuleColliderToUserSize() const } CapsuleColliderComponent->SetWorldRotation(FRotator::ZeroRotator); + + // Counteract Pawn Scaling + CapsuleColliderComponent->SetWorldScale3D(FVector::One()); } void UCollisionHandlingMovement::CheckAndRevertCollisionSinceLastTick() diff --git a/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp b/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp index 812e83ea74b96709e72b7768dbbd5d90bc041f52..f8d78c33e8dcd0bda765bafeb985aa14f266563a 100644 --- a/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp +++ b/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp @@ -18,6 +18,10 @@ #include "Utility/RWTHVRUtilities.h" #if PLATFORM_SUPPORTS_CLUSTER +#include "DisplayClusterRootActor.h" +#include "ScalableConfigInterface.h" +#include "IDisplayCluster.h" +#include "Game/IDisplayClusterGameManager.h" #include "Components/DisplayClusterSceneComponentSyncParent.h" #endif @@ -41,7 +45,21 @@ ARWTHVRPawn::ARWTHVRPawn(const FObjectInitializer& ObjectInitializer) : Super(Ob LeftHand = CreateDefaultSubobject<UReplicatedMotionControllerComponent>(TEXT("Left Hand MCC")); LeftHand->SetupAttachment(RootComponent); + + UniformScale = GetActorScale3D().X; + GetRootComponent()->TransformUpdated.AddLambda( + [this](USceneComponent*, EUpdateTransformFlags, ETeleportType) + { + FVector CurrentScale = this->GetActorScale3D(); + if (CurrentScale.X != UniformScale || CurrentScale.Y != UniformScale || CurrentScale.Z != UniformScale) + { + UE_LOGFMT(Toolkit, Warning, + "ARWTHVRPawn: Do not adjust the scale of the pawn directly. This will not work in VR. Use " + "ARWTHVRPawn::SetScale(float) instead."); + } + }); } + void ARWTHVRPawn::BeginPlay() { Super::BeginPlay(); } void ARWTHVRPawn::Tick(float DeltaSeconds) @@ -56,6 +74,42 @@ void ARWTHVRPawn::Tick(float DeltaSeconds) EvaluateLivelink(); } +/* + * Scales the Pawn. Only supports uniform scaling. + */ +void ARWTHVRPawn::SetScale(float NewScale) +{ + UniformScale = NewScale; + FVector NewScaleVector = FVector(UniformScale, UniformScale, UniformScale); + SetActorRelativeScale3D(NewScaleVector); + +#if PLATFORM_SUPPORTS_CLUSTER + const ARWTHVRPlayerState* State = GetPlayerState<ARWTHVRPlayerState>(); + if (URWTHVRUtilities::IsRoomMountedMode() && State && State->GetCorrespondingClusterActor()) + { + if (const auto GameMgr = IDisplayCluster::Get().GetGameMgr()) + { + if (const auto ClusterRootActor = GameMgr->GetRootActor()) + { + if (ClusterRootActor->Implements<UScalableConfigInterface>()) + { + IScalableConfigInterface::Execute_OnScaleChanged(ClusterRootActor, NewScale); + } + else + { + UE_LOGFMT(Toolkit, Warning, + "The ClusterRootActor {0} does not implement the ScalableConfigInterface. Scaling the " + "Pawn on the cluster will lead to unintended behavior.", + ClusterRootActor->GetName()); + } + } + } + } +#endif +} + +float ARWTHVRPawn::GetScale() { return UniformScale; } + /* * The alternative would be to do this only on the server on possess and check for player state/type, * as connections now send their playertype over. @@ -362,4 +416,4 @@ void ARWTHVRPawn::ApplyLiveLinkTransform(const FTransform& Transform, HeadCameraComponent->SetRelativeScale3D(Transform.GetScale3D()); } } -} +} \ No newline at end of file diff --git a/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h b/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h index cd81e497181dcfef757b067ccae8c862c022fa34..dcd506b1456848cba48f946da63d930b5c651ea1 100644 --- a/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h +++ b/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h @@ -14,6 +14,8 @@ class UCameraComponent; class UMotionControllerComponent; struct FLiveLinkTransformStaticData; +DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnScaleChangedDelegate, FVector, OldScale, float, NewUniformScale); + /** * Pawn implementation with additional VR functionality, can be used in the Cave, with an HMD and on desktop. */ @@ -31,6 +33,15 @@ public: virtual void NotifyControllerChanged() override; + UFUNCTION(BlueprintCallable) + void SetScale(float NewScale); + + UFUNCTION(BlueprintCallable) + float GetScale(); + + UPROPERTY(BlueprintAssignable) + FOnScaleChangedDelegate OnScaleChanged; + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Pawn|Input") TArray<UInputMappingContext*> InputMappingContexts; @@ -111,4 +122,5 @@ protected: private: UInputComponent* ActivePlayerInputComponent; + float UniformScale; };