Tank turret is rotating like a helicopter

Hello guys!
When I start to turn my tank to the right or left, turret starts to rotate crazy, like in the video

https://drive.google.com/file/d/17OuQAl2v42lLX1QI8rgy5h85LCno_2Ep/view?usp=sharing

Please help

That’s a feature! Helicopter Tank, best mode of transport!

(will need to see your code)

Ok, here it is


#include "TankTrack.h"

//Maybe bug is in the amount of force that we give to tank

UTankTrack::UTankTrack()
{
	PrimaryComponentTick.bCanEverTick = false;
	PrimaryComponentTick.bStartWithTickEnabled = false;
	OnComponentHit.AddDynamic(this, &UTankTrack::OnHit);
}


void UTankTrack::OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp,
	FVector NormalImpulse, const FHitResult& Hit)
{
	//We are doing this in other function and setting the throttle when pressing input keys, because we need to prevent applying force when tank is on the air
	DriveTrack();
	ApplyCorrectionForce();
	//Setting to zero to stop applying force
	CurrentThrottle = 0;
}

void UTankTrack::SetThrottle(float Throttle)
{
	CurrentThrottle = FMath::Clamp<float>(CurrentThrottle + Throttle, -1, 1);
}

void UTankTrack::DriveTrack()
{
	//Applying force
	//Calculating force to apply. Equals to 0, if throttle is 0
	FVector ForceToApply = this->GetForwardVector() * CurrentThrottle * TankMaxDrivingForce;
	//Getting track's location to apply a force on it
	FVector ForceLocation = GetComponentLocation();
	//Getting rootcomponent and casting to primitive component for applying force
	UPrimitiveComponent* TankRoot = Cast<UPrimitiveComponent>(GetOwner()->GetRootComponent());
	TankRoot->AddForceAtLocation(ForceToApply, ForceLocation);
}

I meant the code related to the turret rotation.

Alright, here is the MoveBarrelTowards method

void UTankAimingComponent::MoveBarrelTowards(FVector AimingDirection)
{
	if (ensure(!Barrel || !Turret)) return;

	FRotator BarrelRotation = Barrel->GetForwardVector().Rotation();
	FRotator AimAsRotator = AimDirection.Rotation();
	FRotator DeltaRotation = AimAsRotator - BarrelRotation;

	if (FMath::Abs(DeltaRotation.Yaw) < 180)
	{
		Turret->Rotate(DeltaRotation.Yaw);
	}
	else // Avoid going the long-way round
	{
	Turret->Rotate(-DeltaRotation.Yaw);
	}
	Barrel->Elevate(DeltaRotation.Pitch);
}

And here is the Rotate method in TankTurret.cpp

void UTankTurret::Rotate(float RelativeSpeed)
{
	float Time = GetWorld()->GetTimeSeconds();
	
	RelativeSpeed = FMath::Clamp<float>(RelativeSpeed, -1, 1);
	
	//This is where we calculate our elevation from the position before.
	//(DeltaTimeSeconds is for delay between frames, to avoid the slower or faster function running on different machines)
	float RotationChange = RelativeSpeed * MaxDegreesPerSecond * GetWorld()->DeltaTimeSeconds;
	
	float Rotation = GetRelativeRotation().Yaw + RotationChange;
	
	//Sets the rotation of the component relative to its parent
	SetWorldRotation(FRotator(0, Rotation, 0));
}

This doesn’t mean the same thing as what is done in the course. The ensure gives a stack trace if the condition is false, but the early return is wanted if they are false. In other words the ensure wants a truthy value (and will complain if it’s false) but the if condition is for a falsey value so it can exit early.

Your code:

+---------+--------+--------------+---------------+-------------+---------------+
| Barrel  | Turret | ensure Expr  |   if expr.    | exit early? | ensure fired? |
+---------+--------+--------------+---------------+-------------+---------------+
| nullptr | valid  | ensure(true) | true || false | true        | false         |
+---------+--------+--------------+---------------+-------------+---------------+

Course code:

+---------+--------+-------------------------------+---------------+-------------+---------------+
| Barrel  | Turret |          ensure Expr          |   if expr.    | exit early? | ensure fired? |
+---------+--------+-------------------------------+---------------+-------------+---------------+
| nullptr | valid  | ensure(false) || ensure(true) | true || false | true        | true          |
+---------+--------+-------------------------------+---------------+-------------+---------------+

That is the game time not the delta time. It should be GetDeltaSeconds

Yep, my bad, I’ve made Time variable and haven’t used it anywhere. But after these changes my turret doesn’t seem to work properly yet.

Think I might to see your project

Would you mind sending me your project using the following link?

https://gdev.tv/projectupload

Please use File > Package Project > Zip Up Project within Unreal as this will ensure only required files are zipped up and things like the Binaries are excluded.

No problem, sent it

That is the packaged project and not a zipped up project. With that said I didn’t experience any issues with rotation.

What version of Unreal and compiler are you using?

Unreal 4.26 and Rider 2021.1.2

Rider is an IDE not a compiler.

Compiler would be Microsoft Visual Compiler (Visual Studio), AppleClang, GCC, etc.

Oops, sorry. Visual studio then

Specifically what version of that? Did you experience issues with rotation with the packaged game that you sent?

Microsoft Visual Studio Community 2019
Version 16.10.2

Yes, I have the same issue with packaged game

This is what I get with what you sent me

I’m sorry, but I meant when I’m trying to turn my tank tracks by pressing A or D, turret starts to rotate crazy

Oh I’m dumb. Well could you provide your project then?

No prob, sent it

Well I found that hard to spot. But your error is here. Look at the comment and then look at the code.

Privacy & Terms