diff --git a/Source/RWTHVRToolkit/Private/Pawn/VRPawnMovement.cpp b/Source/RWTHVRToolkit/Private/Pawn/VRPawnMovement.cpp
index 8c9df9f768ea38960025f18cf0723f5eab6cb568..ca8cdb48addeb1c2c980c174d6ea413827d5e9f6 100644
--- a/Source/RWTHVRToolkit/Private/Pawn/VRPawnMovement.cpp
+++ b/Source/RWTHVRToolkit/Private/Pawn/VRPawnMovement.cpp
@@ -1,6 +1,7 @@
 
 #include "Pawn/VRPawnMovement.h"
 #include "DrawDebugHelpers.h"
+#include "Kismet/KismetSystemLibrary.h"
 
 UVRPawnMovement::UVRPawnMovement(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
 {
@@ -19,6 +20,9 @@ void UVRPawnMovement::TickComponent(float DeltaTime, enum ELevelTick TickType, F
 
 	if (NavigationMode == EVRNavigationModes::NAV_WALK)
 	{
+		// you are only allowed to move horizontally in NAV_WALK
+		// everything else will be handled by stepping-up/gravity
+		// so remove Z component for the input vector of the UFloatingPawnMovement
 		PositionChange.Z = 0.0f;
 		ConsumeInputVector();
 		AddInputVector(PositionChange);
@@ -26,17 +30,22 @@ void UVRPawnMovement::TickComponent(float DeltaTime, enum ELevelTick TickType, F
 	
 	if(NavigationMode == EVRNavigationModes::NAV_FLY || NavigationMode == EVRNavigationModes::NAV_WALK)
 	{
-		MoveByGravityOrStepUp(DeltaTime);
 		CheckForPhysWalkingCollision();
-
-		if(CheckForVirtualMovCollision(PositionChange, DeltaTime))
+		if(CheckForVirtualSteerCollision(PositionChange, DeltaTime))
 		{
+			// if we would move into something if we apply this input (estimating distance by max speed)
+			// we consume the input so it is not applied
 			ConsumeInputVector();
 		}
+
+		// so we add stepping-up (for both walk and fly)
+		// and gravity for walking only
+		MoveByGravityOrStepUp(DeltaTime);
 	}
 
 	if(NavigationMode == EVRNavigationModes::NAV_NONE)
 	{
+		//just remove whatever input is there
 		ConsumeInputVector();
 	}
 
@@ -45,18 +54,6 @@ void UVRPawnMovement::TickComponent(float DeltaTime, enum ELevelTick TickType, F
 	LastHeadPosition = HeadComponent->GetComponentLocation();
 }
 
-bool UVRPawnMovement::CheckForVirtualMovCollision(FVector PositionChange, float DeltaTime)
-{
-	FVector ProbePosition = PositionChange.GetSafeNormal() * GetMaxSpeed() * DeltaTime;
-	FHitResult FHitResultVR;
-	CapsuleColliderComponent->AddWorldOffset(ProbePosition, true, &FHitResultVR);
-	if (FVector::Distance(FHitResultVR.Location, CapsuleColliderComponent->GetComponentLocation()) < CapsuleColliderComponent->GetScaledCapsuleRadius())
-	{
-		return true;
-	}
-	return false;
-}
-
 void UVRPawnMovement::SetHeadComponent(USceneComponent* NewHeadComponent)
 {
 	HeadComponent = NewHeadComponent;
@@ -68,12 +65,30 @@ void UVRPawnMovement::SetHeadComponent(USceneComponent* NewHeadComponent)
 
 void UVRPawnMovement::SetCapsuleColliderToUserSize()
 {
-	float CharachterSize = abs(UpdatedComponent->GetComponentLocation().Z - HeadComponent->GetComponentLocation().Z);
 
-	if (CharachterSize > MaxStepHeight)
+	// the collider should be placed
+	//	between head and floor + MaxStepHeight
+	//             head
+	//            /    \
+	//           /      \
+	//          |        |
+	//          |        |
+	//          |collider|
+	//          |        |
+	//          |        |
+	//           \      /
+	//            \ __ /
+	//              |
+	//         MaxStepHeight
+	//              |
+	// floor: ______________
+
+	const float UserSize = HeadComponent->GetComponentLocation().Z - UpdatedComponent->GetComponentLocation().Z;
+
+	if (UserSize > MaxStepHeight)
 	{
-		float ColliderHeight = CharachterSize - MaxStepHeight;
-		float ColliderHalfHeight = ColliderHeight / 2.0f;
+		const float ColliderHeight = UserSize - MaxStepHeight;
+		const float ColliderHalfHeight = ColliderHeight / 2.0f;
 		if (ColliderHalfHeight <= CapsuleRadius)
 		{//Make the collider to a Sphere
 			CapsuleColliderComponent->SetCapsuleSize(ColliderHalfHeight, ColliderHalfHeight);
@@ -85,109 +100,88 @@ void UVRPawnMovement::SetCapsuleColliderToUserSize()
 
 		CapsuleColliderComponent->SetWorldLocation(HeadComponent->GetComponentLocation());
 		CapsuleColliderComponent->AddWorldOffset(FVector(0, 0, -ColliderHalfHeight));
-		CapsuleColliderComponent->SetWorldRotation(FRotator(0, 0, 1));
 	}
 	else
 	{
 		CapsuleColliderComponent->SetWorldLocation(HeadComponent->GetComponentLocation());
-		CapsuleColliderComponent->SetWorldRotation(FRotator(0, 0, 1));
 	}
+	CapsuleColliderComponent->SetWorldRotation(FRotator::ZeroRotator);
 }
 
 void UVRPawnMovement::CheckForPhysWalkingCollision()
 {
-	FVector CurrentHeadPosition = HeadComponent->GetComponentLocation();
-	FVector Direction = CurrentHeadPosition - LastHeadPosition;
-	FHitResult FHitResultPhys;
-	CapsuleColliderComponent->AddWorldOffset(Direction, true, &FHitResultPhys);
+	const FHitResult HitResult = CreateCapsuleTrace(LastHeadPosition, HeadComponent->GetComponentLocation(), false);
+
+	//if this was not possible move it the entire pawn to avoid the head collision
+	if (HitResult.bBlockingHit)
+	{
+		UpdatedComponent->AddLocalOffset(HitResult.Normal*HitResult.PenetrationDepth);
+	}
+}
 
-	if (FHitResultPhys.bBlockingHit)
+bool UVRPawnMovement::CheckForVirtualSteerCollision(FVector PositionChange, float DeltaTime)
+{
+	FVector ProbePosition = PositionChange.GetSafeNormal() * GetMaxSpeed() * DeltaTime;
+	const FHitResult HitResult = CreateCapsuleTrace(HeadComponent->GetComponentLocation(), ProbePosition, false);
+	if (HitResult.bBlockingHit)
 	{
-		UpdatedComponent->AddLocalOffset(FHitResultPhys.Normal*FHitResultPhys.PenetrationDepth);
+		return true;
 	}
+	return false;
 }
 
 void UVRPawnMovement::MoveByGravityOrStepUp(float DeltaSeconds)
 {
-	FVector StartLineTraceUnderCollider = CapsuleColliderComponent->GetComponentLocation();
-	StartLineTraceUnderCollider.Z -= CapsuleColliderComponent->GetScaledCapsuleHalfHeight();
-	FHitResult HitDetailsMultiLineTrace = CreateMultiLineTrace(FVector(0, 0, -1), StartLineTraceUnderCollider, CapsuleColliderComponent->GetScaledCapsuleRadius() / 4.0f, false);
-	float DistanceDifference = abs(MaxStepHeight - HitDetailsMultiLineTrace.Distance);
+	const FVector DownTraceStart = CapsuleColliderComponent->GetComponentLocation();
+	const float DownTraceDist = 1000.0f;
+	const FVector DownTraceDir = FVector(0,0,-1);
+	const FVector DownTraceEnd = DownTraceStart + DownTraceDist * DownTraceDir;
+
+	const FHitResult DownTraceHitResult = CreateCapsuleTrace(DownTraceStart, DownTraceEnd, true);
+	float HeightDifference = 0.0f;
+
+	if(DownTraceHitResult.bBlockingHit)
+	{
+		HeightDifference = DownTraceHitResult.ImpactPoint.Z - UpdatedComponent->GetComponentLocation().Z;
+		//so for HeightDifference>0, we have to move the pawn up; for HeightDifference<0 we have to move it down
+	}
 	//Going up (in Fly and Walk Mode)
-	if ((HitDetailsMultiLineTrace.bBlockingHit && HitDetailsMultiLineTrace.Distance < MaxStepHeight))
+	if (HeightDifference>0.0f && HeightDifference<=MaxStepHeight)
+	{
+		ShiftVertically(HeightDifference, UpSteppingAcceleration, DeltaSeconds);
+	}
+
+	if(NavigationMode!=EVRNavigationModes::NAV_WALK)
 	{
-		ShiftVertically(DistanceDifference, UpSteppingAcceleration, DeltaSeconds, 1);
+		return;
 	}
+
 	//Gravity (only in Walk Mode)
-	else if (NavigationMode==EVRNavigationModes::NAV_WALK && ((HitDetailsMultiLineTrace.bBlockingHit && HitDetailsMultiLineTrace.Distance > MaxStepHeight) || (HitDetailsMultiLineTrace.Actor == nullptr && HitDetailsMultiLineTrace.Distance != -1.0f)))
+	if (!DownTraceHitResult.bBlockingHit || HeightDifference<0.0f)
 	{
-		ShiftVertically(DistanceDifference, GravityAcceleration, DeltaSeconds, -1);
+		ShiftVertically(HeightDifference, GravityAcceleration, DeltaSeconds);
 	}
 }
 
-void UVRPawnMovement::ShiftVertically(float DiffernceDistance, float VerticalAcceleration, float DeltaSeconds, int Direction)
+void UVRPawnMovement::ShiftVertically(float Distance, float VerticalAcceleration, float DeltaSeconds)
 {
 	VerticalSpeed += VerticalAcceleration * DeltaSeconds;
-	if (VerticalSpeed*DeltaSeconds < DiffernceDistance)
+	if (abs(VerticalSpeed*DeltaSeconds) < abs(Distance))
 	{
-		UpdatedComponent->AddLocalOffset(FVector(0.f, 0.f, Direction * VerticalSpeed * DeltaSeconds));
+		UpdatedComponent->AddLocalOffset(FVector(0.f, 0.f,  VerticalSpeed * DeltaSeconds));
 	}
 	else
 	{
-		UpdatedComponent->AddLocalOffset(FVector(0.f, 0.f, Direction * DiffernceDistance));
+		UpdatedComponent->AddLocalOffset(FVector(0.f, 0.f,  Distance));
 		VerticalSpeed = 0;
 	}
 }
 
-FHitResult UVRPawnMovement::CreateLineTrace(FVector Direction, const FVector Start, bool Visibility)
+FHitResult UVRPawnMovement::CreateCapsuleTrace(const FVector Start, FVector End, bool DrawDebug) const
 {
-	//Re-initialize hit info
-	FHitResult HitDetails = FHitResult(ForceInit);
-
-	FVector End = ((Direction * 1000.f) + Start);
-	// additional trace parameters
-	FCollisionQueryParams TraceParams(FName(TEXT("InteractTrace")), true, NULL);
-	TraceParams.bTraceComplex = true; //to use complex collision on whatever we interact with to provide better precision.
-	TraceParams.bReturnPhysicalMaterial = true; //to provide details about the physical material, if one exists on the thing we hit, to come back in our hit result.
-
-	if (Visibility)
-		DrawDebugLine(GetWorld(), Start, End, FColor::Green, false, 1, 0, 1);
+	const EDrawDebugTrace::Type DrawType = DrawDebug ? EDrawDebugTrace::Type::ForDuration : EDrawDebugTrace::Type::None;
 
-	if (GetWorld()->LineTraceSingleByChannel(HitDetails, Start, End, ECC_Visibility, TraceParams))
-	{
-		if (HitDetails.bBlockingHit)
-		{
-		}
-	}
-	return HitDetails;
+	FHitResult Hit;
+	UKismetSystemLibrary::CapsuleTraceSingle(GetWorld(), Start, End, CapsuleColliderComponent->GetScaledCapsuleRadius(), CapsuleColliderComponent->GetScaledCapsuleHalfHeight() ,UEngineTypes::ConvertToTraceType(ECollisionChannel::ECC_Visibility), true, {}, DrawType, Hit, true);
+	return Hit;
 }
-
-FHitResult UVRPawnMovement::CreateMultiLineTrace(FVector Direction, const FVector Start, float Radius, bool Visibility)
-{
-	TArray<FVector> StartVectors;
-	TArray<FHitResult> OutHits;
-	FHitResult HitDetailsMultiLineTrace;
-	HitDetailsMultiLineTrace.Distance = -1.0f;//(Distance=-1) not existing, but to know if this Variable not Initialized(when all Traces not compatible)
-
-	StartVectors.Add(Start); //LineTraceCenter
-	StartVectors.Add(Start + FVector(0, -Radius, 0)); //LineTraceLeft
-	StartVectors.Add(Start + FVector(0, +Radius, 0)); //LineTraceRight
-	StartVectors.Add(Start + FVector(+Radius, 0, 0)); //LineTraceFront
-	StartVectors.Add(Start + FVector(-Radius, 0, 0)); //LineTraceBehind
-
-	bool IsBlockingHitAndSameActor = true;
-	bool IsAllNothingHiting = true;
-	// loop through TArray
-	for (FVector& Vector : StartVectors)
-	{
-		FHitResult OutHit = CreateLineTrace(Direction, Vector, Visibility);
-		OutHits.Add(OutHit);
-		IsBlockingHitAndSameActor &= (OutHit.Actor == OutHits[0].Actor); //If all Hiting the same Object, then you are (going up/down) or (walking)
-		IsAllNothingHiting &= (OutHit.Actor == nullptr); //If all Hiting nothing, then you are falling
-	}
-
-	if (IsBlockingHitAndSameActor || IsAllNothingHiting)
-		HitDetailsMultiLineTrace = OutHits[0];
-
-	return HitDetailsMultiLineTrace;
-}
\ No newline at end of file