AI Driver script doesn't work

Hey there

i wrote an script for an AI Driver in my car race. This AI should find his way with help of waypoints.
The problem is, my car drive, but not in the way it should.

here is the code for the rotation function:

	void steelWheels(Vector3 targetPosition){           //targetPostion gets the position of the current waypoint
		
		float a = targetPosition.z - LenkTransform.transform.localPosition.z;                 // lenktransform is the object where the car is.
		float b = targetPosition.x - LenkTransform.transform.localPosition.x;
		
		float rot = a / b;
		float rota = Mathf.Atan(rot);              //this should be the angle the wheelcollider has to use
		
		Debug.Log(rota);
			
		leftFrontWheel.steerAngle = rota;
		rightFrontWheel.steerAngle = leftFrontWheel.steerAngle;
}

i hope you can find my mistake(s) and can correct me.

greetings

DubStepMaster

Hey,
I think your problem is getting the direction.

        float a = targetPosition.z - LenkTransform.transform.localPosition.z;                 // lenktransform is the object where the car is.

        float b = targetPosition.x - LenkTransform.transform.localPosition.x;

        

        float rot = a / b;

        float rota = Mathf.Atan(rot);              //this should be the angle the wheelcollider has to use

First of all,if your waypoint is not parented to the same object your LenkTransform is parented to,you shouldn’t use local space.Try to make both LenkTransform and your targetPosition global vectors.

So it would be:

        float Z = targetPosition.z - LenkTransform.transform.position.z;

        float X = targetPosition.x - LenkTransform.transform.position.x;

Then,i don’t think it’s right to divide a by b…The formula for getting the direction is : (targetPosition - LenkTransform.position).normalized.You get the x or z component of that and then you transform that to angles.

(By the way,say directly that rightFrontWheel.steerAngle = rota.It’s a tiny bit faster than having Unity to get leftFrontWheel.steerAngle)

(Try this one,not tested)

    void steelWheels(Vector3 targetPosition){           //targetPostion gets the position of the current waypoint

      
   Vector3 Dir = (targetPosition - LenkTransform.transform.position).normalized;
        
        float rot = Dir.y * 180; //Or x,or Z,i'm not sure which one you have there...

        Debug.Log(rot);

            

        leftFrontWheel.steerAngle = rot;

        rightFrontWheel.steerAngle = rot;

}

Good luck!

thanks for answering so fast

the problem currently exist…
my script looks like that:

	void steelWheels(Vector3 targetPosition){
		Vector3 direction = (targetPosition - LenkTransform.transform.position).normalized;
		//float a = targetPosition.z - LenkTransform.transform.position.z;
		//float b = targetPosition.x - LenkTransform.transform.position.x;
		
		float rota = direction.z / direction.x;
		float rota = Mathf.Atan(rot);
		
			
		leftFrontWheel.steerAngle = rota;
		rightFrontWheel.steerAngle = rota;
}

i don’t see it

Well,why do you divide dir.z by dir.x?Is it a trick i don’t know about?

float rot = Dir.y * 180; Does not work?

no it doesn’t work…

erm, ok, here are a couple of easy ai thoughts. U can take them as u need them, or just not use them, ur choice.

First, convert the targets position to a local position, and make sure Y is zero.
Next, get the angle between the target and the object. u can use Vector3.angle to get it.
Next, u need to know if that angle is left or right of the vehicle, Left is a negative angle, right is positive ( or the other way around) Use the target.x. If it is positive, it is on the right, negative, left.
Next, use the target.z to figure out if it is in front or back. positive, front, negative back.
Now, we need to convert this to steer and gas inputs, just like a player. To do this, all we have to do is hold a max steer angle, and divide our angle by that, then clamp it to -1 and 1. Gas is either -1 or 1 and that is it.

lastly, u need to use the gas as a measure. If ur backing up, reverse the steering.

Alternatively, u can use Vector3.Dot to get the gas info. If it is greater or less than an amount, u can change ur forward and back directions at different angles.

Simple code

using UnityEngine;
using System.Collections;

public class test : MonoBehaviour {
	
	public float maxSteer = 40;
	// Use this for initialization
	void Start () {
		
	}
	
	// Update is called once per frame
	void Update () {
		
		transform.LookAt(transform.position + Camera.main.transform.up, -Camera.main.transform.forward);
		Plane plane = new Plane(Camera.main.transform.forward, transform.position);
		Ray ray = Camera.main.camera.ScreenPointToRay(Input.mousePosition);
		float dist;
		if(plane.Raycast(ray, out dist)){
			Vector3 localPoint = transform.InverseTransformPoint(ray.GetPoint(dist));
			localPoint.y = 0;
			float steer = Vector3.Angle(localPoint , transform.forward);
			steer = (localPoint.x < 0 ? -steer : steer) / maxSteer;
			steer = Mathf.Clamp (steer, -1, 1);
			float gas = localPoint.z < 0 ? -1 : 1;
			// alternative to local.z
			gas = Vector3.Dot(Vector3.forward, localPoint.normalized) > 0.2f ? 1 : -1;
			steer = gas == 1 ? steer : -steer;
			
			Debug.Log ( "Steer: " + steer + ", " + "Gas: " + gas );
			//Debug.Log( steer);
		}
	}
}

here is my new code:

void steelWheels(Vector3 targetPosition){
		Vector3 punkteins = LenkTransform.transform.position;
		punkteins = new Vector3(punkteins.x, 0, punkteins.z);
		
		Vector3 punktzwei = targetPosition;
		punktzwei = new Vector3(punktzwei.x, 0,punktzwei.z);
		
		float angle = Vector3.Angle(punkteins, punktzwei);
		
		
		Debug.Log(angle.ToString());
		
		
		if(punktzwei.x > punkteins.x){
			//der wp liegt vor uns
			if(punktzwei.z > punkteins.z){
				//fall 1
				if(Umkehrung==true){
					angle = Mathf.Abs(angle) * (- 1.0f);
				}else{
					angle = Mathf.Abs(angle);
				}
				
			}
			if(punktzwei.z < punkteins.z){
				//fall 2
				if(Umkehrung==false){
					angle = Mathf.Abs(angle) * (- 1.0f);
				}else{
					angle = Mathf.Abs(angle);
				}
			}
		}
		
		if(punktzwei.x < punkteins.x){
			//der wp liegt hinter uns
			if(punktzwei.z > punkteins.z){
				if(Umkehrung==false){
					angle = Mathf.Abs(angle) * (- 1.0f);
				}else{
					angle = Mathf.Abs(angle);
				}
				//fall 1
			}
			if(punktzwei.z < punkteins.z){
				if(Umkehrung==true){
					angle = Mathf.Abs(angle) * (- 1.0f);
				}else{
					angle = Mathf.Abs(angle);
				}
				//fall 2
			}
		}

		
		leftFrontWheel.steerAngle = angle;
		rightFrontWheel.steerAngle = angle;
	
		leftFrontWheelD.localEulerAngles = new Vector3(leftFrontWheelD.localEulerAngles.x, leftFrontWheel.steerAngle - leftFrontWheelD.localEulerAngles.z, leftFrontWheelD.localEulerAngles.z);
		rightFrontWheelD.localEulerAngles = new Vector3(rightFrontWheelD.localEulerAngles.x, rightFrontWheel.steerAngle - rightFrontWheelD.localEulerAngles.z, rightFrontWheelD.localEulerAngles.z);
	}

but this doesn’t work
my car drives where it wants and not over the waypoints

i need help please

here is the whole code i need for this steering:

public class AIGegner : MonoBehaviour {
	
	public bool Umkehrung = false;
	
	public List<Transform> waypoints;
	private int curWayp =0;
	private int manyWayp;
	public GameObject LenkTransform;
	
	public float minDistance = 1.0f;
	void Start () {
		manyWayp = waypoints.Count;
	}
	void Update(){
		curWP(); //calculate the curWayp
		Vector3 curTarget = waypoints[curWayp].transform.localPosition;
		steelWheels(curTarget);			
	}
void steelWheels(Vector3 targetPosition){
		Vector3 punkteins = LenkTransform.transform.position;
		punkteins = new Vector3(punkteins.x, 0, punkteins.z);
		
		Vector3 punktzwei = targetPosition;
		punktzwei = new Vector3(punktzwei.x, 0,punktzwei.z);
		
		float angle = Vector3.Angle(punkteins, punktzwei);
				
		if(punktzwei.x > punkteins.x){
			//der wp liegt vor uns
			if(punktzwei.z > punkteins.z){
				//fall 1
				Debug.Log("Fall1");
				if(Umkehrung==true){
					angle = Mathf.Abs(angle) * (- 1.0f);
				}else{
					angle = Mathf.Abs(angle);
				}
				
			}
			if(punktzwei.z < punkteins.z){
				//fall 2
				Debug.Log("Fall2");
				if(Umkehrung==false){
					angle = Mathf.Abs(angle) * (- 1.0f);
				}else{
					angle = Mathf.Abs(angle);
				}
			}
		}
		
		if(punktzwei.x < punkteins.x){
			//der wp liegt hinter uns
			Debug.Log("Fall3");
			if(punktzwei.z > punkteins.z){
				if(Umkehrung==false){
					angle = Mathf.Abs(angle) * (- 1.0f);
				}else{
					angle = Mathf.Abs(angle);
				}
				//fall 1
			}
			if(punktzwei.z < punkteins.z){
				Debug.Log("Fall4");
				if(Umkehrung==true){
					angle = Mathf.Abs(angle) * (- 1.0f);
				}else{
					angle = Mathf.Abs(angle);
				}
				//fall 2
			}
		}
				
		leftFrontWheel.steerAngle = angle;
		rightFrontWheel.steerAngle = angle;
	
	}
	void curWP(){
		Vector3 curPoint = LenkTransform.transform.position;
		curPoint = new Vector3(curPoint.x,0,curPoint.z);
		
		Vector3 curWP = waypoints[curWayp].transform.position;
		curWP = new Vector3(curWP.x,0,curWP.z);
		
		Vector3 delta = curWP - curPoint;
		if (delta.magnitude < minDistance){
			curWayp++;
			Debug.Log("Next Waypoint");
			Debug.Log(curWayp.ToString());
		}
		
	}

the angle of this never is higher than around 3

why??

please help a poor man

I wish for you to understand these lines:

float maxSteer = 40;
Vector3 localPoint = transform.InverseTransformPoint( targetPosition );
localPoint.y = 0;
float steer = Vector3.Angle(localPoint , transform.forward);
steer = localPoint.x < 0 ? -steer : steer;
steer = Mathf.Clamp (steer, -maxSteer , maxSteer );
float gas = Vector3.Dot(Vector3.forward, localPoint.normalized) > 0.2f ? 1 : -1;

gas is the amount of direction to push, so gas * force for wheel force

ok thanks

the problem is now, that the wheel colliders flipping arount between negativ and positiv

i don’t know why

post all of your code u are using so I can test it. (or pm me with it if u dont want it in the public view)