Download

Smooth Vaulting System

hello!! hope you are all doing well.

Explanation of what is actually happening:
I have been working on vaulting system, I’m using 3 line traces, one for if I’m close enough to vault, one for calculating wall height and the other one for wall thickness to give the character choice of vaulting or climbing.

Main Problem and Question:
everything works fine but for more smooth movement I want to set rotation before vaulting using
FInterp function but have no idea how to do it, any thoughts?

thank you in advance for your help :slight_smile:

Code for 3 Line Traces:

//LineTrace Variables
	FHitResult Hit;
	FVector StartLocation {GetActorLocation()};
	FVector EndLocation {StartLocation + GetActorForwardVector() * 80};
	FCollisionObjectQueryParams ObjectsToTrace;
	ObjectsToTrace.AddObjectTypesToQuery(ECollisionChannel::ECC_WorldStatic);
	FCollisionQueryParams ActorsToIgnore;
	ActorsToIgnore.AddIgnoredActor(this);
	
	//LineTrace if we are close enough to Vault or Climb
	GetWorld()->LineTraceSingleByObjectType(Hit,StartLocation,EndLocation,ObjectsToTrace,ActorsToIgnore);
	//DrawDebugLine(GetWorld(),StartLocation,EndLocation,FColor::Red,true);

	if(Hit.Component == nullptr)
	{
		ShouldClimb = false;
		return false;
	}
	
	//HitLocation
	FVector FrontHitLocation = Hit.Location;
	
	//Calculate Start And End Locations for Second LineTrace Which Calculates The Wall Height
	FVector WallLocation {Hit.Location};
	FVector WallNormal {Hit.Normal};
	FRotator WallNormalRotationX = UKismetMathLibrary::MakeRotFromX(WallNormal);
	FVector WallNormalForwardVector = UKismetMathLibrary::GetForwardVector(WallNormalRotationX);
	StartLocation = WallNormalForwardVector * -5;
	StartLocation += WallLocation;
	StartLocation +=  {0,0,200};
	EndLocation = StartLocation;
	EndLocation -= {0,0,200};
	
	//LineTrace For Wall Height
	GetWorld()->LineTraceSingleByObjectType(Hit,StartLocation,EndLocation,ObjectsToTrace,ActorsToIgnore);
	//DrawDebugLine(GetWorld(),StartLocation,EndLocation,FColor::Red,true);
	
	//WallHeight
	FVector TopHitLocation {Hit.Location};
	float WallHeight{0};
	if(Hit.Component != nullptr)
	{
		WallHeight = TopHitLocation.Z;
		WallHeight -=FrontHitLocation.Z;
	}
	
	//Calculate Start And End Locations for Third LineTrace Which Calculates The Wall Thickness
	StartLocation = WallNormalForwardVector * -50;
	StartLocation += WallLocation;
	StartLocation +=  {0,0,200};
	EndLocation = StartLocation;
	EndLocation -= {0,0,200};

	//LineTrace For Wall Thickness
	GetWorld()->LineTraceSingleByObjectType(Hit,StartLocation,EndLocation,ObjectsToTrace,ActorsToIgnore);
	//DrawDebugLine(GetWorld(),StartLocation,EndLocation,FColor::Red,true);

	//WallThickness
	FVector TopFarHitLocation {Hit.Location};
	float WallThickness{0};
	if(Hit.Component != nullptr)
	{
		WallThickness = UKismetMathLibrary::Abs(TopFarHitLocation.X - TopHitLocation.X);
		if(WallThickness < 1)
		{
			WallThickness = UKismetMathLibrary::Abs(TopFarHitLocation.Y - TopHitLocation.Y);
		}
	}

You need to call FMath::FinterpTo inside the event tick, because as you can see on the docs (FMath::FInterpTo | Unreal Engine Documentation), the method FinterpTo needs a DeltaTime parameter, which can be found inside the event tick. Anyway if you want to interpolate a FRotator you could use FMath::RInterpTo, but the principle is the same.
Here I made an example:

.h file

UCLASS()
class AMyClass : public AActor
{
    UPROPERTY()
    FRotator NewRotation;

    UPROPERTY()
    AActor* ActorToRotate;

    UFUNCTION()
    void SetNewInterpolatedRotation(const FRotator& InNewRotation);
}

.cpp file:

AMyClass::SetNewInterpolatedRotation(AActor* InActor, const FRotator& InNewRotation)
{
    ActorToRotate = InActor;
    NewRotation = InNewRotation;
}

void AMyClass::Tick(float DeltaSeconds)
{
    Super::Tick(DeltaSeconds);
    if (ActorToRotate != nullptr && NewRotation != FRotator::ZeroRotator)
    {
        ActorToRotate->SetActorRelativeRotation(FMath::RInterpTo(ActorToRotate->GetActorRotation(), NewRotation, DeltaSeconds, 5.f);
    }
}

In this example you can simply call SetNewInterpolatedRotation to set the new example actor rotation, and the event tick will change it smoothly.

I really appreciate your help, I was working on it for a week.
it is working smooth now.
Thank you Again.