Well, I got it all to work - I posted the code below for anyone to see and benefit.
I found that the Mathf.Lerp function was a decent cheat, but it only worked well at low velocity. As the rigidbody gains speed, Lerp falls short and the vehicle begins to oscillate back and forth and criss cross the intercept vector.
So I needed to dig down deep in my old tired brain and figure out the proper math from my physics/calculus college days. The math is essentiallty:
var turnBack = Mathf.Pow(curTurnAngle,2) * maxTurn/deltaSteer;
turnBack is the value in the if statement that tells the vehicle to begin to come out of the turn to wind up at zero turning angle when it reaches the intercept vector.
I’m not sure if the math is exactly correct, but it works. I have to explicitly set the curTurnAngle to zero when it’s on course or the vehicle goes wonky when it should go straight on course by itself. So that’s an unfortunate kludge for now. I probably have a if/else mistake somewhere in my code.
But it all works like a charm now - very realistic and smooth.
The rest of the code deals with incrementing or decrementing the turn angle but not going over the maximum turning angle for the vehicle. Not shown in this code snippet is the vehicle motor force and the part where the values get passed to the wheels script.
Anyway, thanks for all the help and suggestions - I’m posting the code in the hopes it will help someone else.
If anyone can suggest improvements (I’m a relative newbie at programming), please let me know.
Mitch
// stuff for intercept
var closingVelocity = Vector3.zero - rigidbody.velocity; // since the targetpoint is not moving, it's velocity is zero
var closingRange = targetPoint - transform.position;
var closingTime = closingRange.magnitude/closingVelocity.magnitude;
var predictedPosition = targetPoint + (Vector3.zero * closingTime);
// distance to target
var targetDistance = Vector3.Distance (transform.position, predictedPosition);
// when we reach the targetPoint, generate a new target
if (targetDistance < 5)
targetPoint = Vector3 (Random.Range (-100, 100), .5, Random.Range (-100, 100));
// convert global corordinates to local coordinates
var localTargetPoint = transform.InverseTransformPoint (predictedPosition);
// and normalize it
Vector3.Normalize (localTargetPoint);
// what is current angle to the target
var curAngleToTarget = Vector3.Angle(localTargetPoint, Vector3.forward);
// is it a positive or negative angle?
if (localTargetPoint.x < 0)
curAngleToTarget = -curAngleToTarget;
// turnbackangle is the point in the turn where we have to begin to come out of the turn for proper smooth intercept
var turnBack = Mathf.Pow(curTurnAngle,2) * maxTurn/deltaSteer;
if (curAngleToTarget > 0) // turn right
{
if ((curAngleToTarget > turnBack) (curTurnAngle < maxTurn)) // turn, but don't go over the maximum turning angle
curTurnAngle += deltaSteer*Time.deltaTime;
if (curAngleToTarget < turnBack) // turn back, but don't go past zero
{
curTurnAngle -= deltaSteer*Time.deltaTime;
if (curTurnAngle < 0)
curTurnAngle = 0;
}
}
if (curAngleToTarget < 0) // turn left
{
if ((curAngleToTarget < -turnBack) (curTurnAngle > -maxTurn)) // turn, but don't go over the maximum turning angle
curTurnAngle -= deltaSteer*Time.deltaTime;
if (curAngleToTarget > -turnBack) // turn back, but don't go past zero
{
curTurnAngle += deltaSteer*Time.deltaTime;
if (curTurnAngle > 0)
curTurnAngle = 0;
}
}
if (curAngleToTarget == 0)
curTurnAngle = 0;