Aoredon
(Aoredon)
August 2, 2015, 1:59pm
13
Okay doing my own version is going to take longer than I thought to set-up but, here’s a trimmed-down version of how i handle steering in my Hovertank game using rotation around Axes, and avoid gimbal lock regardless of orientation. My object simulates physics however, but the basic idea is the same:
Legend:
OmegaSpin = Turn Speed
AlphaSteer = How fast craft responds to steering input.
SteerValue = Current value from the mouse X-axis for steering.
Up = Actor Up Vector
Omega = Current Angular Velocity in World-Space (WS)
LSOmega = Current Angular Velocity in Local-Space
/* Velocity & Angular Rotation */
Omega = UpdatedPrimitive->GetPhysicsAngularVelocity(); // Set Omega Initial Value
FVector LSOmega = UpdatedPrimitive->GetComponentToWorld().InverseTransformVector(Omega); // Omega In Local Space
FVector SteerVal = FVector::ZeroVector;
if (OmegaSpin > 0.f)
{
/* We Need Local-Space Omega, Since Steering Is Applied In Local Space. */
SteerVal.Z = AlphaSteer * FMath::Clamp(SteerValue - LSOmega.Z / OmegaSpin, -1.0f, 1.0f);
}
else
{
SteerVal.Z = 0.f;
}
Alpha += Up * SteerVal;
Omega += Alpha * TimeStep;
UpdatedPrimitive->SetPhysicsAngularVelocity(Omega);
Edit: Adding to this…
What I would do in your case is Figure out the World-Space position of the Reticle (and make sure it’s somewhere in front of the craft). Then I’d get the normalized direction from the craft to that location, and Dot-Product it against the crafts Right Vector and Up Vectors - and multiply it by some value to determine the strength at which the craft rotates towards it. Something like:
FVector Direction = GetActorLocation() - ReticlePositionWS();
float RightDot = FVector::DotProduct(GetActorRightVector(), Direction) * CraftRotationSpeed;
float UpDot= FVector::DotProduct(GetActorUpVector(), Direction) * CraftRotationSpeed;
FVector Alpha = FVector((GetActorUpVector() * RightDot) + (GetActorRightVector() * UpDot));
Essentially you can use the Dot Products as a way to control how much rotational ‘force’ to apply, since as they start facing 90 degrees to each other, they’ll get closer and closer to zero. What you’ll effectively have is a rotational-spring.
Edit 2: As it’s a spring, you’ll probably also want some kind of damping too:
Alpha += FVector(AlphaDamp * Omega);
If this doesn’t work still let me know, I think you may have to use an extra Cross-Product just before the Dot Product… especially if the craft can ‘Roll’
Hey, thanks for this. It’s been really helpful!
However, the only component my pawn has was a UChildActorComponent which for some reason you can’t do much or any physics stuff with it, so I created a UPrimitiveComponent and set as the root component for the pawn, but applying angular velocity to it does nothing and when it says the angular velocity is 0, 0, 0. Any ideas? I tried setting simulate physics to true, but printing out whether or not physics is enabled returns false. I also called the function to wake the rigid body, but that doesn’t seem to do anything either.