Adding corrective force in MovementComponent instead of Tracks

From a logical point of view, I decided to move the corrective force calculations into the Tank Movement Component instead of the tracks.
This actually makes more sense to me. Use the tank overall right speed, and by that do the same calculation for the complete tank instead. This avoids the “double” code execution on each track, each one just doing half of the corrective force and makes the correction in one single step.
The Code itself is basically the same:

void UTankMovementComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction * ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);	// so that it ticks in BP as well, not needed in our case, but...
	
	if (sidewaysCorrectionActive) {
		// Apply corrective force to whole tank to compensate sideways movement
		auto TankRoot = Cast<UStaticMeshComponent>(GetOwner()->GetRootComponent());

		auto RightSpeed = FVector::DotProduct(TankRoot->GetRightVector(), TankRoot->GetComponentVelocity());
		auto Acceleration = -RightSpeed / DeltaTime * TankRoot->GetRightVector();
		// Force = m * a
		auto Force = TankRoot->GetMass() * Acceleration;
		GEngine->AddOnScreenDebugMessage(4, 2.0f, FColor::Blue, FString::Printf(TEXT("RightSpeed: %f, Correction: %s"), RightSpeed, *Force.ToString()));
		TankRoot->AddForce(Force);	// Adding force at the tank location itself
	}
}

BTW: I made the correction switchable in game using F12 key, that’s where the sidewaysCorrectionActive parameter comes from.

1 Like

Well, when proceeding the course, I reverted this back to the tank tracks, as now the forces are only applied when having hit events. So we need the separate handling and the functionality is not always called twice.

Privacy & Terms