Skip to content
Snippets Groups Projects
Commit a07d88d9 authored by Daniel Rupp's avatar Daniel Rupp
Browse files

Updated VRPawn to use EnhancedInputSystem, Renamed VRPawnMovement to...

Updated VRPawn to use EnhancedInputSystem, Renamed VRPawnMovement to ContinuousMovementComponent and added Snap turn and Handedness switching
parent 68187463
Branches
Tags
1 merge request!13Draft: Improve walking implementation
Showing
with 398 additions and 0 deletions
File added
File added
File added
File added
File added
File added
File added
File added
File added
File added
File added
File added
File added
File added
File added
File added
No preview for this file type
File added

#include "Pawn/VRPawnMovement.h"
// Fill out your copyright notice in the Description page of Project Settings.
#include "Pawn/ContinuousMovementComponent.h"
#include "DrawDebugHelpers.h"
#include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "Engine/LocalPlayer.h"
#include "GameFramework/PlayerController.h"
#include "Pawn/VRPawnInputConfig.h"
#include "Utility/VirtualRealityUtilities.h"
UVRPawnMovement::UVRPawnMovement(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
UContinuousMovementComponent::UContinuousMovementComponent(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
CapsuleColliderComponent = CreateDefaultSubobject<UCapsuleComponent>(TEXT("CapsuleCollider"));
CapsuleColliderComponent->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
CapsuleColliderComponent->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Overlap);
CapsuleColliderComponent->SetCollisionResponseToChannel(ECollisionChannel::ECC_WorldStatic, ECollisionResponse::ECR_Block);
CapsuleColliderComponent->SetCapsuleSize(CapsuleRadius, 80.0f);
VRPawn = Cast<AVirtualRealityPawn>(GetOwner());
}
void UVRPawnMovement::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction){
void UContinuousMovementComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction){
SetCapsuleColliderToUserSize();
......@@ -45,7 +58,18 @@ void UVRPawnMovement::TickComponent(float DeltaTime, enum ELevelTick TickType, F
LastHeadPosition = HeadComponent->GetComponentLocation();
}
bool UVRPawnMovement::CheckForVirtualMovCollision(FVector PositionChange, float DeltaTime)
void UContinuousMovementComponent::BeginPlay()
{
Super::BeginPlay();
SetUpdatedComponent(VRPawn->GetRootComponent());
SetHeadComponent(VRPawn->CapsuleRotationFix);
SetupInputActions();
}
bool UContinuousMovementComponent::CheckForVirtualMovCollision(FVector PositionChange, float DeltaTime)
{
FVector ProbePosition = PositionChange.GetSafeNormal() * GetMaxSpeed() * DeltaTime;
FHitResult FHitResultVR;
......@@ -57,7 +81,7 @@ bool UVRPawnMovement::CheckForVirtualMovCollision(FVector PositionChange, float
return false;
}
void UVRPawnMovement::SetHeadComponent(USceneComponent* NewHeadComponent)
void UContinuousMovementComponent::SetHeadComponent(USceneComponent* NewHeadComponent)
{
HeadComponent = NewHeadComponent;
CapsuleColliderComponent->SetupAttachment(HeadComponent);
......@@ -66,7 +90,7 @@ void UVRPawnMovement::SetHeadComponent(USceneComponent* NewHeadComponent)
CapsuleColliderComponent->SetWorldLocation(FVector(0.0f, 0.0f,HalfHeight));
}
void UVRPawnMovement::SetCapsuleColliderToUserSize()
void UContinuousMovementComponent::SetCapsuleColliderToUserSize()
{
float CharachterSize = abs(UpdatedComponent->GetComponentLocation().Z - HeadComponent->GetComponentLocation().Z);
......@@ -94,7 +118,7 @@ void UVRPawnMovement::SetCapsuleColliderToUserSize()
}
}
void UVRPawnMovement::CheckForPhysWalkingCollision()
void UContinuousMovementComponent::CheckForPhysWalkingCollision()
{
FVector CurrentHeadPosition = HeadComponent->GetComponentLocation();
FVector Direction = CurrentHeadPosition - LastHeadPosition;
......@@ -107,7 +131,7 @@ void UVRPawnMovement::CheckForPhysWalkingCollision()
}
}
void UVRPawnMovement::MoveByGravityOrStepUp(float DeltaSeconds)
void UContinuousMovementComponent::MoveByGravityOrStepUp(float DeltaSeconds)
{
FVector StartLineTraceUnderCollider = CapsuleColliderComponent->GetComponentLocation();
StartLineTraceUnderCollider.Z -= CapsuleColliderComponent->GetScaledCapsuleHalfHeight();
......@@ -125,7 +149,7 @@ void UVRPawnMovement::MoveByGravityOrStepUp(float DeltaSeconds)
}
}
void UVRPawnMovement::ShiftVertically(float DiffernceDistance, float VerticalAcceleration, float DeltaSeconds, int Direction)
void UContinuousMovementComponent::ShiftVertically(float DiffernceDistance, float VerticalAcceleration, float DeltaSeconds, int Direction)
{
VerticalSpeed += VerticalAcceleration * DeltaSeconds;
if (VerticalSpeed*DeltaSeconds < DiffernceDistance)
......@@ -139,7 +163,71 @@ void UVRPawnMovement::ShiftVertically(float DiffernceDistance, float VerticalAcc
}
}
FHitResult UVRPawnMovement::CreateLineTrace(FVector Direction, const FVector Start, bool Visibility)
void UContinuousMovementComponent::SetupInputActions()
{
// simple way of changing the handedness
if(bMoveWithRightHand)
{
MovementHand = VRPawn->RightHand;
RotationHand = VRPawn->LeftHand;
IMCMovement = IMCMovementRight;
} else
{
MovementHand = VRPawn->LeftHand;
RotationHand = VRPawn->RightHand;
IMCMovement = IMCMovementLeft;
}
const APlayerController* PlayerController = Cast<APlayerController>(VRPawn->GetController());
UEnhancedInputLocalPlayerSubsystem* InputSubsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer());
if(!InputSubsystem)
{
UE_LOG(LogTemp,Error,TEXT("InputSubsystem IS NOT VALID"));
return;
}
InputSubsystem->ClearAllMappings();
// add Input Mapping context
InputSubsystem->AddMappingContext(IMCMovement,0);
UEnhancedInputComponent* EI = Cast<UEnhancedInputComponent>(VRPawn->InputComponent);
if(!EI)
{
UE_LOG(LogTemp,Error,TEXT("Cannot cast Input Component to Enhanced Inpu Component in VRPawnMovement"));
return;
}
// walking
EI->BindAction(InputActions->Move, ETriggerEvent::Triggered, this, &UContinuousMovementComponent::OnBeginMove);
// turning
if(bSnapTurn && !UVirtualRealityUtilities::IsDesktopMode())
{
EI->BindAction(InputActions->Turn, ETriggerEvent::Started, this, &UContinuousMovementComponent::OnBeginSnapTurn);
} else
{
EI->BindAction(InputActions->Turn, ETriggerEvent::Triggered, this, &UContinuousMovementComponent::OnBeginTurn);
}
// bind functions for desktop rotations only on holding down right mouse
if (UVirtualRealityUtilities::IsDesktopMode())
{
APlayerController* PC = Cast<APlayerController>(VRPawn->GetController());
if (PC)
{
PC->bShowMouseCursor = true;
PC->bEnableClickEvents = true;
PC->bEnableMouseOverEvents = true;
}
EI->BindAction(InputActions->DesktopRotation, ETriggerEvent::Started, this, &UContinuousMovementComponent::StartDesktopRotation);
EI->BindAction(InputActions->DesktopRotation, ETriggerEvent::Completed, this, &UContinuousMovementComponent::EndDesktopRotation);
}
}
FHitResult UContinuousMovementComponent::CreateLineTrace(FVector Direction, const FVector Start, bool Visibility)
{
//Re-initialize hit info
FHitResult HitDetails = FHitResult(ForceInit);
......@@ -162,7 +250,7 @@ FHitResult UVRPawnMovement::CreateLineTrace(FVector Direction, const FVector Sta
return HitDetails;
}
FHitResult UVRPawnMovement::CreateMultiLineTrace(FVector Direction, const FVector Start, float Radius, bool Visibility)
FHitResult UContinuousMovementComponent::CreateMultiLineTrace(FVector Direction, const FVector Start, float Radius, bool Visibility)
{
TArray<FVector> StartVectors;
TArray<FHitResult> OutHits;
......@@ -191,3 +279,115 @@ FHitResult UVRPawnMovement::CreateMultiLineTrace(FVector Direction, const FVecto
return HitDetailsMultiLineTrace;
}
void UContinuousMovementComponent::StartDesktopRotation()
{
bApplyDesktopRotation = true;
}
void UContinuousMovementComponent::EndDesktopRotation()
{
bApplyDesktopRotation = false;
}
void UContinuousMovementComponent::OnBeginMove(const FInputActionValue& Value)
{
const FVector ForwardDir = UVirtualRealityUtilities::IsDesktopMode() ? VRPawn->Head->GetForwardVector() : MovementHand->GetForwardVector();
const FVector RightDir = UVirtualRealityUtilities::IsDesktopMode() ? VRPawn->Head->GetRightVector() : MovementHand->GetRightVector();
if (VRPawn->Controller != nullptr)
{
const FVector2D MoveValue = Value.Get<FVector2D>();
const FRotator MovementRotation(0, VRPawn->Controller->GetControlRotation().Yaw, 0);
// Forward/Backward direction
if (MoveValue.X != 0.f)
{
VRPawn->AddMovementInput(ForwardDir, MoveValue.X);
}
// Right/Left direction
if (MoveValue.Y != 0.f)
{
VRPawn->AddMovementInput(RightDir, MoveValue.Y);
}
}
}
void UContinuousMovementComponent::OnBeginTurn(const FInputActionValue& Value)
{
if(UVirtualRealityUtilities::IsDesktopMode() && !bApplyDesktopRotation) return;
if (VRPawn->Controller != nullptr)
{
const FVector2D TurnValue = Value.Get<FVector2D>();
if (TurnValue.X != 0.f)
{
VRPawn->AddControllerYawInput(TurnRateFactor * TurnValue.X);
if (UVirtualRealityUtilities::IsDesktopMode())
{
UpdateRightHandForDesktopInteraction();
}
}
if (TurnValue.Y != 0.f)
{
if (UVirtualRealityUtilities::IsDesktopMode() && bApplyDesktopRotation)
{
VRPawn->AddControllerPitchInput(TurnRateFactor * TurnValue.Y);
SetCameraOffset();
}
}
}
}
void UContinuousMovementComponent::OnBeginSnapTurn(const FInputActionValue& Value)
{
const FVector2D TurnValue = Value.Get<FVector2D>();
if (TurnValue.X != 0.f)
{
VRPawn->AddControllerYawInput(SnapTurnAngle);
}
}
void UContinuousMovementComponent::SetCameraOffset() const
{
// this also incorporates the BaseEyeHeight, if set as static offset,
// rotations are still around the center of the pawn (on the floor), so pitch rotations look weird
FVector Location;
FRotator Rotation;
VRPawn->GetActorEyesViewPoint(Location, Rotation);
VRPawn->CameraComponent->SetWorldLocationAndRotation(Location, Rotation);
}
void UContinuousMovementComponent::UpdateRightHandForDesktopInteraction()
{
APlayerController* PC = Cast<APlayerController>(GetController());
if (PC)
{
FVector MouseLocation, MouseDirection;
PC->DeprojectMousePositionToWorld(MouseLocation, MouseDirection);
FRotator HandOrientation = MouseDirection.ToOrientationRotator();
VRPawn->RightHand->SetWorldRotation(HandOrientation);
}
}
/*void UContinuousMovementComponent::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
Super::PostEditChangeProperty(PropertyChangedEvent);
FName PropertyName = (PropertyChangedEvent.Property != NULL) ? PropertyChangedEvent.Property->GetFName() : NAME_None;
if (PropertyName == GET_MEMBER_NAME_CHECKED(AVirtualRealityPawn, bMoveWithRightHand) ||
PropertyName == GET_MEMBER_NAME_CHECKED(AVirtualRealityPawn, bSnapTurn))
{
// if we want to change input bindings, we need to setup the player input again to load a different mapping context,
// or assign a different function to an input action.
// This is automatically done by restarting the pawn(calling SetupPlayerInputComponent() directly results in crashes)
// only do this in the editor
#if WITH_EDITOR
VRPawn->Restart();
#endif
}
}*/
\ No newline at end of file
// Fill out your copyright notice in the Description page of Project Settings.
#include "Pawn/VRPawnInputConfig.h"
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment