Hello guys!
I'm prototyping a race game and I was looking for a way to reduce the steer angle, using C++.
In this code, I have a angle value, called AxisDeviation, to define a MoveForward range.
Here is the video:
https://youtu.be/gCkzBRzzbjo
How can I reduce both the steer angle and the steer rotation rate, to solve the problem found in this video?
A guy on Reddit told me to find a InputSteerRiseRate variable inside the UWheeledVehicleMovementComponent. I didn't find a InputSteerRiseRate variable or a InputSteerFallRate, but I did find instead a FVehicvleInputRate called SteeringInputRate, that contains floats called RiseRate and FallRate, but it's a protected variable and there is no Getter to access it. There is another way?
He also told me that the SteerAngle is inside the UVehicleWheel (indeed), but I should avoid it, otherwise I have to recalculate the ackermann angle. I was looking for the ackermann angle, but I didn't find it inside the engine code. Any clues?
Any help will be appreciated!
Thanks!
I'm prototyping a race game and I was looking for a way to reduce the steer angle, using C++.
In this code, I have a angle value, called AxisDeviation, to define a MoveForward range.
Code:
// Fill out your copyright notice in the Description page of Project Settings. #include "MoveForwardTask.h" #include "GameFramework/Pawn.h" #include "BehaviorTree/BehaviorTreeTypes.h" #include "BehaviorTree/BehaviorTreeComponent.h" #include "BehaviorTree/BlackboardComponent.h" #include "BehaviorTree/Blackboard/BlackboardKeyType_Vector.h" #include "UObject/UObjectGlobals.h" #include "CarAIController.h" #include "NPCCarPawn.h" #include "Blackboard_keys.h" #include "Components/SplineComponent.h" #include "Components/SplineMeshComponent.h" #include "SplineActor.h" #include "Kismet/KismetMathLibrary.h" #include "WheeledVehicleMovementComponent.h" #include "DrawDebugHelpers.h" #include "Engine/GameEngine.h" #include "WheeledVehicleMovementComponent4W.h" UMoveForwardTask::UMoveForwardTask(const FObjectInitializer& ObjectInitializer) {NodeName = TEXT("Move Forward");} EBTNodeResult::Type UMoveForwardTask::ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) {const ACarAIController* CarController = Cast<ACarAIController>(OwnerComp.GetAIOwner()); ANPCCarPawn* CarPawn = Cast<ANPCCarPawn>(CarController->GetPawn()); FVector ClosestPoint = CarPawn->GetTrackCircuit()->GetSplineComponent()->FindLocationClosestToWorldLocation(CarPawn->GetActorLocation(), ESplineCoordinateSpace::World); DrawDebugLine(GetWorld(), CarPawn->GetActorLocation(), ClosestPoint, FColor::Red, false, 180.f, 3.f); ASplineActor* CurrentTrack = CarPawn->GetTrackCircuit(); float LineTraceLength = 300.f; FVector LeftTraceStart, MiddleTraceStart, RightTraceStart; FVector LeftTraceEnd, MiddleTraceEnd, RightTraceEnd; LeftTraceStart = MiddleTraceStart = RightTraceStart = CarPawn->GetActorLocation() + FVector(0.f, 0.f, 25.f); LeftTraceEnd = LeftTraceStart + (CarPawn->GetActorForwardVector().ToOrientationRotator() + FRotator(-6.f, -22.5f, 0.f)).Vector() * LineTraceLength; MiddleTraceEnd = MiddleTraceStart + (CarPawn->GetActorForwardVector().ToOrientationRotator() + FRotator(-6.f, 0.f, 0.f)).Vector() * LineTraceLength; RightTraceEnd = RightTraceStart + (CarPawn->GetActorForwardVector().ToOrientationRotator() + FRotator(-6.f, 22.5f, 0.f)).Vector() * LineTraceLength; FCollisionQueryParams TraceParams(TEXT("Circuit Trace"), true, CarPawn); TraceParams.bTraceComplex = true; TraceParams.bReturnPhysicalMaterial = true; TArray<ASplineActor*> TrackCircuitArr = CarPawn->GetTrackCircuitArray(); for(int Index = 0; Index < TrackCircuitArr.Num(); Index++){if(TrackCircuitArr[Index] != CurrentTrack) {TraceParams.AddIgnoredActor(TrackCircuitArr[Index]);}} FHitResult LeftTraceHitDetails = FHitResult(ForceInit); FHitResult MiddleTraceHitDetails = FHitResult(ForceInit); FHitResult RightTraceHitDetails = FHitResult(ForceInit); bool bLeftTraceStroke = CarPawn->GetWorld()->LineTraceSingleByChannel(LeftTraceHitDetails, LeftTraceStart, LeftTraceEnd, ECC_WorldStatic, TraceParams); bool bMiddleTraceStroke = CarPawn->GetWorld()->LineTraceSingleByChannel(MiddleTraceHitDetails, MiddleTraceStart, MiddleTraceEnd, ECC_WorldStatic, TraceParams); bool bRightTraceStroke = CarPawn->GetWorld()->LineTraceSingleByChannel(RightTraceHitDetails, RightTraceStart, RightTraceEnd, ECC_WorldStatic, TraceParams); if(bLeftTraceStroke) {DrawDebugLine(CarPawn->GetWorld(), LeftTraceStart, LeftTraceEnd, FColor::Orange, false, .05f, ECC_WorldStatic, 2.5f); DrawDebugPoint(CarPawn->GetWorld(), LeftTraceHitDetails.ImpactPoint, 50.f, FColor:: Green, false, .05f, ECC_WorldStatic); UE_LOG(LogTemp, Warning, TEXT("Actor hit by the left trace: %s"), *LeftTraceHitDetails.Actor->GetName());} if (bMiddleTraceStroke) {DrawDebugLine(CarPawn->GetWorld(), MiddleTraceStart, MiddleTraceEnd, FColor::Orange, false, .05f, ECC_WorldStatic, 2.5f); DrawDebugPoint(CarPawn->GetWorld(), MiddleTraceHitDetails.ImpactPoint, 50.f, FColor:: Green, false, .05f, ECC_WorldStatic); UE_LOG(LogTemp, Warning, TEXT("Actor hit by the middle trace: %s"), *MiddleTraceHitDetails.Actor->GetName());} if (bRightTraceStroke) {DrawDebugLine(CarPawn->GetWorld(), RightTraceStart, RightTraceEnd, FColor::Orange, false, .05f, ECC_WorldStatic, 2.5f); DrawDebugPoint(CarPawn->GetWorld(), RightTraceHitDetails.ImpactPoint, 50.f, FColor:: Green, false, .05f, ECC_WorldStatic); UE_LOG(LogTemp, Warning, TEXT("Actor hit by the right trace: %s"), *RightTraceHitDetails.Actor->GetName());} if(CarPawn->CanMove()) {//ASplineActor* CurrentTrack = CarPawn->GetTrackCircuit(); float angle = CarPawn->CalculateAngleBetween(); if (CarPawn->IsTravellingReverseMode()) {angle = angle - 180.f;} float AxisDeviation = CarPawn->GetAxisDeviation(); //UWheeledVehicleMovementComponent4W* Vehicle4W = CastChecked<UWheeledVehicleMovementComponent4W>(CarPawn->GetVehicleMovement()); //Vehicle4W->Wheels[0].SteerAngle = 15.f; /* if(GEngine) { GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Orange, FString::Printf(TEXT("Angle = %f"), angle)); } */ UE_LOG(LogTemp, Warning, TEXT("Angle = %s"), *FString::Printf(TEXT("%f"), angle)); if (((angle >= -AxisDeviation && angle <= AxisDeviation) || (angle >= (180 - AxisDeviation) || angle <= (-180 + AxisDeviation))) && (LeftTraceHitDetails.Actor == CurrentTrack && MiddleTraceHitDetails.Actor == CurrentTrack && RightTraceHitDetails.Actor == CurrentTrack)) {CarPawn->MoveForward(1); UE_LOG(LogTemp, Warning, TEXT("MOVING FORWARD"));} else {if((LeftTraceHitDetails.Actor != CurrentTrack &&MiddleTraceHitDetails.Actor == CurrentTrack && RightTraceHitDetails.Actor == CurrentTrack) || (LeftTraceHitDetails.Actor != CurrentTrack && MiddleTraceHitDetails.Actor != CurrentTrack && RightTraceHitDetails.Actor == CurrentTrack) || (LeftTraceHitDetails.Actor == CurrentTrack && MiddleTraceHitDetails.Actor == CurrentTrack && RightTraceHitDetails.Actor == CurrentTrack && (angle > AxisDeviation && angle < (180 - AxisDeviation)) )) {CarPawn->MoveRight(1); UE_LOG(LogTemp, Warning, TEXT("MOVING RIGHT"));} else {if ((LeftTraceHitDetails.Actor == CurrentTrack && MiddleTraceHitDetails.Actor == CurrentTrack && RightTraceHitDetails.Actor != CurrentTrack) || (LeftTraceHitDetails.Actor == CurrentTrack && MiddleTraceHitDetails.Actor != CurrentTrack && RightTraceHitDetails.Actor != CurrentTrack) || (LeftTraceHitDetails.Actor == CurrentTrack && MiddleTraceHitDetails.Actor == CurrentTrack && RightTraceHitDetails.Actor == CurrentTrack && (angle < -AxisDeviation && angle > (-180 + AxisDeviation)))) {CarPawn->MoveRight(-1); UE_LOG(LogTemp, Warning, TEXT("MOVING LEFT"));}}}} FinishLatentTask(OwnerComp, EBTNodeResult::Succeeded); return EBTNodeResult::Succeeded;}
https://youtu.be/gCkzBRzzbjo
How can I reduce both the steer angle and the steer rotation rate, to solve the problem found in this video?
A guy on Reddit told me to find a InputSteerRiseRate variable inside the UWheeledVehicleMovementComponent. I didn't find a InputSteerRiseRate variable or a InputSteerFallRate, but I did find instead a FVehicvleInputRate called SteeringInputRate, that contains floats called RiseRate and FallRate, but it's a protected variable and there is no Getter to access it. There is another way?
He also told me that the SteerAngle is inside the UVehicleWheel (indeed), but I should avoid it, otherwise I have to recalculate the ackermann angle. I was looking for the ackermann angle, but I didn't find it inside the engine code. Any clues?
Any help will be appreciated!
Thanks!

Comment