# smoothing problem

I am trying to make an vehicle AI, to make it turn to stay on track at a certain distance from a reference point which moves along the Z axis in the middle of the track. The track is shaped like a hippodrome so the reference object moves from max Z to min Z and when it reaches the center of the circle which describes the end curves of the hippodrome it stops moving on the Z axis and rotates to LookAt the front wheel collider of the vehicle. The said vehicle must stay within the bounds of the hippodrome, and must move along the circuit by keeping a set distance from the reference point which i can modify to make it turn on the track. The problem is that although it keeps the vehicle on the track, the collider is not making smooth turns, and if i use lerpAngle with a slower speed, it doesn’t turn fast enough, is there any other way to calculate the steering angle based on that reference which gives a smoother result in steering?

Here’s the code I use:

``````using UnityEngine;
using System.Collections;

public class AutoSteer : MonoBehaviour {

/*
floats for autosteering
refDistMin	 		- the minimum distance from the reference point to the vehicles front wheel collider
refDistMax			- the maximum distance from the reference point to the vehicles front wheel collider
minDistance		- minimum offset from said distance
maxDistance		- maximum offset from said distance
distance 			- actual distance from the vehicles front wheel collider to the reference point (we want to stay within it's bounds)
steer				- unused
refDist			- unused
translationSpeed	- the speed with which we modify the distance from the reference (used for steering)
MaxSteeringAngle	- the maximum steering angle the front wheel collider can support
dist				- the temporary distance from the reference point to the front wheel collider (used for steerAngle calculation)
actualAngle 		- used to calculate the steerAngle
colliderFL			- front wheel collider
reference 			- reference GameObject (empty gameobject)
*/

private float minDistance;
private float maxDistance;
private float refDistMin;
private float refDistMax;
private float distance;
private float steer;
private float refDist;
private float translationSpeed;
private float MaxSteeringAngle;

//some other vars
private float dist;
private float lastAngle;
private float actualAngle;

//gameobjects for autosteering
private WheelCollider colliderFL;
private GameObject reference;

public GameObject Reference{
set { reference = value; }
get { return reference; }
}
void Start () {
//declare each variable
MaxSteeringAngle = 20;
minDistance = 0.1f;
maxDistance = 0.1f;
refDistMax = 50;
refDistMin = 40;
translationSpeed = 3;
steer = 0;
//setting the front wheel collider
colliderFL = gameObject.GetComponent<GetComponents>().ColliderFront();
dist = Vector3.Distance(reference.transform.position, colliderFL.transform.position);
//do some other stuff

}
private void autoSteer(float _band){
distance = Vector3.Distance(reference.transform.position, transform.localPosition);
actualAngle = - Vector3.Angle(-reference.transform.right, colliderFL.transform.forward);
Debug.Log(actualAngle + " " + Vector3.Angle(Vector3.Project(reference.transform.position, colliderFL.transform.position), colliderFL.transform.position));
[COLOR="red"]		if(distance > _band + maxDistance){
actualAngle += MaxSteeringAngle * (_band + maxDistance - distance);
}
else
if(distance < _band - minDistance){
actualAngle += MaxSteeringAngle * (_band - minDistance - distance);
}[/COLOR]
//tried Lerp, LerpAngle etc.
colliderFL.steerAngle = Mathf.MoveTowardsAngle(colliderFL.steerAngle, actualAngle, Time.time);
}
void Update () {
if(gameObject.name != "AIBike"){
if(Input.GetAxis("Horizontal") != 0){
dist += Input.GetAxis("Horizontal") * translationSpeed * Time.deltaTime;
if(dist < refDistMin)
dist = refDistMin;
if(dist > refDistMax)
dist = refDistMax;
}
}
autoSteer(dist);
}
``````

I hope you can understand my problem (english is not my primary language) and any help would be very apreciated.

PS: I am working with unity for aprox a month now, so I am still very green, and i know in this case the problem is with the red code, but i have no ideea how to make it any other way.

bump. anyone?

I do not know if this will help, this is a portion of a basicAI that I put into a tutorial on here. It has to do with the angle that a vehicle should steer to get from where it is now to a waypoint. (it just seems to me like you are missing something in your script)

``````function doDriving(){ // drive towards the target
var position=transform.InverseTransformPoint(waypoint.transform.position);
var angle=Vector3.Angle(Vector3.forward, position);
angle=Vector3.Dot(Vector3.right, position)>0 ? angle : -angle;

//define the steering, left or right
steer=-1.0;
if(angle>=0)steer=1.0;

drive=1.0;
if(Mathf.Abs(angle)>120.0){
drive=-1.0;
steer=-steer;
}

steer=Mathf.Clamp(Mathf.Abs(angle),0.0,VC.veloSteer)*steer/VC.veloSteer;

// reduce drive if our angle is above the amount that we want to steer
//if(drive>0.0){
//	position=transform.InverseTransformPoint(waypoint.next.transform.position);
//	var angle2=Vector3.Angle(Vector3.forward, position);
//	angle2=Vector3.Dot(Vector3.right, position)>0 ? angle2 : -angle2;
//	var mps=rigidbody.velocity.magnitude;
//
//	if(Mathf.Abs(angle + angle2)/2>VC.veloSteer/3)
//		drive= 1-timidness01;
//}

VC.inputSteer=steer;
VC.inputPower=drive;
}
``````

I used some of your code, to know the side on which the ‘waypoint’ is. and the best solution i found for my problem was to attach another empty game object to the reference, and make it stay in front of the player (like a constant waypoint). i tried to smooth out everywhere i could with Vector.LerpAngle and Mathf smoothing functions (Lerp, movetowards etc.) and i still get some jittery motion here and there, but it’s better.

Thanks a bunch BigMisterB.