EDIT: Found the problem, and it’s a problem that a lot of people can have. Previously, without the on hit, the player tank moved perfectly, but the AI tanks were always applying force, so they just flew off. With this solution, the AI tanks seemed to work well, but not mine. That seems to be due to the terrain. On flat surfaces the Tank works perfectly, so the bad control problems are caused due to the imperfections of the terrain. Not always the Tracks were touching the ground, that’s why the erratic behaviour.
I’m having problems with the last section of the Tanks, with the suspension, the suspension does not attach properly. Due to other bugs (The tank always lost his components when compile) I’ve remade a new TankBlueprint and I will see if that fixes the suspension problems.
OLD COMMENT:
Once reached this point in the course, if the functions of On Hit (DriveTrack, ApplySidewaysForce, and reset Throotle) are called from there, the tank doesn’t move, but Unreal enter and executes properly all of them, but when they are called from SetThrottle, making the game follow the same logic that was before, it works perfect (except for applying forces when they are not touching the ground, which is the point of the whole video).
When the calls are made from OnHit, if the max throotle force is increased, it gets to move, but the movement is erratic, it moves by itself to the sides, and it only reacts to the movement in one input (You have to let go forward and start moving right, pressing both buttons doesn’t work)
Here is the code:
include "TankTrack.h"
UTankTrack::UTankTrack()
{
PrimaryComponentTick.bCanEverTick = false;
}
void UTankTrack::BeginPlay()
{
Super::BeginPlay();
OnComponentHit.AddDynamic(this, &UTankTrack::OnHit);
}
void UTankTrack::OnHit(UPrimitiveComponent *HitComponent, AActor *OtherActor, UPrimitiveComponent *OtherComponent, FVector NormalImpulse, const FHitResult &Hit)
{
//UE_LOG(LogTemp, Warning, TEXT("You have reached top speed"));
DriveTrack();
CorrectSidewayForce();
currentThrottle = 0;
}
void UTankTrack::CorrectSidewayForce()
{
auto slippageSpeed = FVector::DotProduct(GetRightVector(), GetComponentVelocity());
auto DeltaTime = GetWorld()->GetDeltaSeconds();
auto correction = slippageSpeed / DeltaTime * -GetRightVector();
auto tankRoot = Cast<UStaticMeshComponent>(GetOwner()->GetRootComponent());
tankRoot->AddForce(correction * tankRoot->GetMass() / 2); //There are two tracks, so the force must be divided
}
void UTankTrack::SetThrottle(float throttle)
{
currentThrottle = FMath::Clamp<float>(currentThrottle + throttle, -1.0f, 1.0f);
//DriveTrack();
//CorrectSidewayForce();
//currentThrottle = 0;
}
void UTankTrack::DriveTrack()
{
UE_LOG(LogTemp, Warning, TEXT("You have reached top speed"));
auto forceApplied = GetForwardVector() * currentThrottle * trackMaxDrivingForce;
auto tankRoot = Cast<UPrimitiveComponent>(GetOwner()->GetRootComponent());
tankRoot->AddForceAtLocation(forceApplied, GetComponentLocation());
}
UFUNCTION() is set before the OnHit function in the header file.
Anyone knows how this could be solved?
Thank you for your time.