// Fill out your copyright notice in the Description page of Project Settings. #include "Pawn/Navigation/TurnComponent.h" #include "EnhancedInputComponent.h" #include "Camera/CameraComponent.h" #include "Pawn/RWTHVRPawn.h" #include "Utility/RWTHVRUtilities.h" void UTurnComponent::SetupPlayerInput(UInputComponent* PlayerInputComponent) { Super::SetupPlayerInput(PlayerInputComponent); if (!VRPawn || !VRPawn->HasLocalNetOwner()) { return; } // simple way of changing the handedness if (bTurnWithLeftHand) { RotationHand = VRPawn->LeftHand; } else { RotationHand = VRPawn->RightHand; } UEnhancedInputComponent* EI = Cast<UEnhancedInputComponent>(PlayerInputComponent); if (!EI) { UE_LOG(Toolkit, Error, TEXT("Cannot cast Input Component to Enhanced Inpu Component in VRPawnMovement")); return; } // turning if (bAllowTurning) { if (bSnapTurn) { // no snap turning for desktop mode if (!URWTHVRUtilities::IsDesktopMode()) { EI->BindAction(Turn, ETriggerEvent::Started, this, &UTurnComponent::OnBeginSnapTurn); } else { EI->BindAction(DesktopTurn, ETriggerEvent::Triggered, this, &UTurnComponent::OnBeginTurn); } } else { if (!URWTHVRUtilities::IsDesktopMode()) { EI->BindAction(Turn, ETriggerEvent::Triggered, this, &UTurnComponent::OnBeginTurn); } else { EI->BindAction(DesktopTurn, ETriggerEvent::Triggered, this, &UTurnComponent::OnBeginTurn); } } } // bind additional functions for desktop rotations if (URWTHVRUtilities::IsDesktopMode()) { EI->BindAction(DesktopTurnCondition, ETriggerEvent::Started, this, &UTurnComponent::StartDesktopRotation); EI->BindAction(DesktopTurnCondition, ETriggerEvent::Completed, this, &UTurnComponent::EndDesktopRotation); } } // A separate button has to be pressed, for when mouse movement should contribute to turning void UTurnComponent::StartDesktopRotation() { bApplyDesktopRotation = true; } void UTurnComponent::EndDesktopRotation() { bApplyDesktopRotation = false; } void UTurnComponent::OnBeginTurn(const FInputActionValue& Value) { if (URWTHVRUtilities::IsDesktopMode() && !bApplyDesktopRotation) return; if (!VRPawn || !VRPawn->Controller) return; const FVector2D TurnValue = Value.Get<FVector2D>(); if (TurnValue.X != 0.f) { if (URWTHVRUtilities::IsDesktopMode() && bApplyDesktopRotation) { VRPawn->AddControllerYawInput(TurnRateFactor * TurnValue.X); } else { RotateCameraAndPawn(TurnRateFactor * TurnValue.X); } } if (TurnValue.Y != 0.f) { if (URWTHVRUtilities::IsDesktopMode() && bApplyDesktopRotation) { VRPawn->AddControllerPitchInput(TurnRateFactor * -TurnValue.Y); } } } void UTurnComponent::OnBeginSnapTurn(const FInputActionValue& Value) { if (!VRPawn || !VRPawn->Controller) return; const FVector2D TurnValue = Value.Get<FVector2D>(); if (TurnValue.X > 0.f) { RotateCameraAndPawn(SnapTurnAngle); } else if (TurnValue.X < 0.f) { RotateCameraAndPawn(-SnapTurnAngle); } } void UTurnComponent::RotateCameraAndPawn(float Yaw) const { const FVector OrigLocation = VRPawn->HeadCameraComponent->GetComponentLocation(); const FRotator OrigRotation = VRPawn->GetActorRotation(); const FRotator NewRotation = FRotator(0, VRPawn->GetActorRotation().Yaw + Yaw, 0); const FVector Offset = VRPawn->GetActorLocation() - OrigLocation; const FVector UntwistedOffset = OrigRotation.GetInverse().RotateVector(Offset); const FVector NewLocation = OrigLocation + NewRotation.RotateVector(UntwistedOffset); VRPawn->Controller->SetControlRotation(NewRotation); VRPawn->SetActorLocationAndRotation(NewLocation, NewRotation); }