Car Game - Problem when creating AI (JS to C#)

Hello!

I’ve been watching a How to make a Car Game -Youtube series for a while now, and since it is done in JS I have been translating it to C# on the go.

I’ve had some problems along the way but I’ve always found a solution sooner or later, but now I think that I am genuinely stuck.

The problem: I’ve created sensors with Raycast that detect if there are objects in front of the car, but I can’t see them while in play mode. Also when the car detects an object it starts to turn left, and just keeps turning left until I exit game mode.

Can you find any translation errors in the following script? I am sorry that this post is going to be long.

Here is the js script as seen in the video series:

var centerOfMass : Vector3;  
var path : Array;  
var pathGroup : Transform;  
var maxSteer : float = 15.0;  
var wheelFL : WheelCollider;   
var wheelFR : WheelCollider;  
var wheelRL : WheelCollider;   
var wheelRR : WheelCollider;  
var currentPathObj : int;  
var distFromPath : float = 20;  
var maxTorque : float = 50;  
var currentSpeed : float;  
var topSpeed : float = 150;  
var decellarationSpeed : float = 10;  
var breakingMesh : Renderer;  
var idleBreakLight : Material;  
var activeBreakLight : Material;  
var isBreaking : boolean;  
var inSector : boolean;  
var sensorLength : float = 5;  
var frontSensorStartPoint : float = 5;  
var frontSensorSideDist : float = 5;  
var frontSensorsAngle : float = 30;  
var sidewaySensorLength : float = 5;  
var avoidSpeed : float = 10;  
private var flag : int = 0;  
var reversing : boolean = false;  
var reverCounter : float = 0.0;  
var waitToReverse : float = 2.0;  
var reverFor : float = 1.5;  
var respawnWait: float = 5;  
var respawnCounter : float = 0.0;  
  
  
  
function Start () {  
rigidbody.centerOfMass = centerOfMass;  
GetPath();  
}  
  
function GetPath (){  
var path_objs : Array = pathGroup.GetComponentsInChildren(Transform);  
path = new Array();  
  
for (var path_obj : Transform in path_objs){  
 if (path_obj != pathGroup)  
  path [path.length] = path_obj;  
}  
}  
  
  
function Update () {  
if (flag == 0)  
GetSteer();  
Move();  
BreakingEffect ();  
Sensors();  
Respawn ();  
}  
  
function GetSteer(){  
var steerVector : Vector3 = transform.InverseTransformPoint(Vector3(path[currentPathObj].position.x,transform.position.y,path[currentPathObj].position.z));  
var newSteer : float = maxSteer * (steerVector.x / steerVector.magnitude);  
wheelFL.steerAngle = newSteer;  
wheelFR.steerAngle = newSteer;  
  
if (steerVector.magnitude <= distFromPath){  
currentPathObj++;  
if (currentPathObj >= path.length)  
currentPathObj = 0;  
}  
  
}  
  
function Move (){  
currentSpeed = 2*(22/7)*wheelRL.radius*wheelRL.rpm * 60 / 1000;  
currentSpeed = Mathf.Round (currentSpeed);  
if (currentSpeed <= topSpeed && !inSector){  
if (!reversing){  
wheelRL.motorTorque = maxTorque;  
wheelRR.motorTorque = maxTorque;  
}  
else {  
wheelRL.motorTorque = -maxTorque;  
wheelRR.motorTorque = -maxTorque;  
}  
wheelRL.brakeTorque = 0;  
wheelRR.brakeTorque = 0;  
}  
else if (!inSector){  
wheelRL.motorTorque = 0;  
wheelRR.motorTorque = 0;  
wheelRL.brakeTorque = decellarationSpeed;  
wheelRR.brakeTorque = decellarationSpeed;  
}  
}  
  
function BreakingEffect (){  
if (isBreaking){  
breakingMesh.material = activeBreakLight;  
}  
else {  
breakingMesh.material = idleBreakLight;  
}  
  
}  
  
function Sensors(){  
flag = 0;  
var avoidSenstivity : float = 0;  
var pos : Vector3;  
var hit : RaycastHit;  
var rightAngle = Quaternion.AngleAxis(frontSensorsAngle,transform.up) * transform.forward;  
var leftAngle = Quaternion.AngleAxis(-frontSensorsAngle,transform.up) * transform.forward;  
  
  
  
pos = transform.position;  
pos += transform.forward*frontSensorStartPoint;  
  
//BRAKING SENSOR  
  
if (Physics.Raycast(pos,transform.forward,hit,sensorLength)){  
if (hit.transform.tag != "Terrain"){  
flag++;  
wheelRL.brakeTorque = decellarationSpeed;  
wheelRR.brakeTorque = decellarationSpeed;  
Debug.DrawLine(pos,hit.point,Color.red);  
}  
}  
else {  
wheelRL.brakeTorque = 0;  
wheelRR.brakeTorque = 0;  
}  
  
  
//Front Straight Right Sensor  
pos += transform.right*frontSensorSideDist;  
  
if (Physics.Raycast(pos,transform.forward,hit,sensorLength)){  
if (hit.transform.tag != "Terrain"){  
flag++;  
avoidSenstivity -= 1;   
Debug.Log("Avoiding");  
Debug.DrawLine(pos,hit.point,Color.white);  
}  
}  
else if (Physics.Raycast(pos,rightAngle,hit,sensorLength)){  
if (hit.transform.tag != "Terrain"){  
avoidSenstivity -= 0.5;   
flag++;  
Debug.DrawLine(pos,hit.point,Color.white);  
}  
}  
  
  
//Front Straight left Sensor  
pos = transform.position;  
pos += transform.forward*frontSensorStartPoint;  
pos -= transform.right*frontSensorSideDist;  
  
if (Physics.Raycast(pos,transform.forward,hit,sensorLength)){  
if (hit.transform.tag != "Terrain"){  
flag++;  
avoidSenstivity += 1;   
Debug.Log("Avoiding");  
Debug.DrawLine(pos,hit.point,Color.white);  
}  
}  
else if (Physics.Raycast(pos,leftAngle,hit,sensorLength)){  
if (hit.transform.tag != "Terrain"){  
flag++;  
avoidSenstivity += 0.5;  
Debug.DrawLine(pos,hit.point,Color.white);  
}  
}  
  
//Right SideWay Sensor  
if (Physics.Raycast(transform.position,transform.right,hit,sidewaySensorLength)){  
if (hit.transform.tag != "Terrain"){  
flag++;  
avoidSenstivity -= 0.5;  
Debug.DrawLine(transform.position,hit.point,Color.white);  
}  
}  
  
  
//Left SideWay Sensor  
if (Physics.Raycast(transform.position,-transform.right,hit,sidewaySensorLength)){  
if (hit.transform.tag != "Terrain"){  
flag++;  
avoidSenstivity += 0.5;  
Debug.DrawLine(transform.position,hit.point,Color.white);  
}  
}  
  
pos = transform.position;  
pos += transform.forward*frontSensorStartPoint;  
//Front Mid Sensor  
if (avoidSenstivity == 0){  
  
if (Physics.Raycast(pos,transform.forward,hit,sensorLength)){  
if (hit.transform.tag != "Terrain"){  
if (hit.normal.x < 0 )  
avoidSenstivity = -1;  
else   
avoidSenstivity = 1;  
Debug.DrawLine(pos,hit.point,Color.white);  
}  
}  
}  
  
  
if (rigidbody.velocity.magnitude < 2 && !reversing){  
reverCounter += Time.deltaTime;  
if (reverCounter >= waitToReverse){  
reverCounter = 0;  
reversing = true;  
}  
}  
else if (!reversing){  
reverCounter = 0;   
}  
  
  
if (reversing){  
avoidSenstivity *= -1;  
reverCounter += Time.deltaTime;  
if (reverCounter >= reverFor){  
reverCounter = 0;  
reversing = false;  
}  
}  
  
  
if (flag != 0)  
AvoidSteer (avoidSenstivity);  
  
  
}  
  
  
function AvoidSteer (senstivity : float){  
wheelFL.steerAngle = avoidSpeed*senstivity;  
wheelFR.steerAngle = avoidSpeed*senstivity;  
  
}  
  
  
function Respawn (){  
if (rigidbody.velocity.magnitude < 2){  
respawnCounter += Time.deltaTime;  
if (respawnCounter >= respawnWait){  
if (currentPathObj == 0){  
transform.position = path[path.length-1].position;  
}  
else{  
transform.position = path[currentPathObj-1].position;  
}  
respawnCounter = 0;  
transform.localEulerAngles.z = 0;  
}  
}  
} 

and here is my C# version of the same script:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class AICarScript : MonoBehaviour
{
		public Vector3 centerOfMass;
		public List<Transform> path;
		public Transform pathGroup;
		public float maxSteer = 15;
		public WheelCollider wheelFL;
		public WheelCollider wheelFR;
		public WheelCollider wheelBL;
		public WheelCollider wheelBR;
		public int currentPathObj;
		public float distFromPath = 20;
		public float maxTorque = 50;
		public float currentSpeed;
		public float topSpeed = 150;
		public float decelerationSpeed = 10;
		public Renderer brakingMesh;
		public Material idleBrakeLight;
		public Material activeBrakeLight;
		public bool isBraking;
		public bool inSector;
		public float sensorLength = 5;
		public float frontSensorStartPoint = 5;
		public float frontSensorSideDistance = 5;
		public float frontSensorsAngle = 30;
		public float sidewaySensorLength = 5;
		public float avoidSpeed = 10;
		private int flag = 0;

		void Start ()
		{
				rigidbody.centerOfMass = centerOfMass;
				getPath ();
		}

		void getPath ()
		{
				Transform[] path_objs = pathGroup.GetComponentsInChildren<Transform> ();
				path = new List<Transform> ();
				foreach (Transform path_obj in path_objs) {
						if (path_obj != pathGroup)
								path.Add (path_obj);
				}

		}

		void Update ()
		{
				if (flag == 0) {
						getSteer ();
						Move ();
						BrakingEffect ();
						Sensors ();
				}
		}

		void getSteer ()
		{
				Vector3 steerVector = transform.InverseTransformPoint (new Vector3 (path [currentPathObj].position.x, transform.position.y, path [currentPathObj].position.z));
				float newSteer = maxSteer * (steerVector.x / steerVector.magnitude);
				wheelFL.steerAngle = newSteer;
				wheelFR.steerAngle = newSteer;

				if (steerVector.magnitude <= distFromPath) {
						currentPathObj++;	
						if (currentPathObj >= path.Count) {
								currentPathObj = 0;
						}
				}
		}

		void Move ()
		{
				currentSpeed = 2 * (22 / 7) * wheelBL.radius * wheelBL.rpm * 60 / 1000;
				currentSpeed = Mathf.Round (currentSpeed);
				if (currentSpeed <= topSpeed && !inSector) {
						wheelBR.motorTorque = maxTorque;
						wheelBL.motorTorque = maxTorque;
						wheelBR.brakeTorque = 0;
						wheelBL.brakeTorque = 0;	
				} else if (!inSector) {
						wheelBR.motorTorque = 0;
						wheelBL.motorTorque = 0;
						wheelBR.brakeTorque = decelerationSpeed;	
						wheelBL.brakeTorque = decelerationSpeed;	
				}

		}

		void BrakingEffect ()
		{
				if (isBraking) {
						brakingMesh.material = activeBrakeLight;
				} else {
						brakingMesh.material = idleBrakeLight;
				}	
		}

		void Sensors ()
		{
				flag = 0;
				float avoidSensitivity = 0;
				Vector3 pos;
				RaycastHit hit;
				Vector3 rightAngle = Quaternion.AngleAxis (frontSensorsAngle, transform.up) * transform.forward;
				Vector3 leftAngle = Quaternion.AngleAxis (-frontSensorsAngle, transform.up) * transform.forward;

				pos = transform.position;
				pos += transform.forward * frontSensorStartPoint;

				// Braking sensor
				if (Physics.Raycast (pos, transform.forward, out hit, sensorLength)) {
						if (hit.transform.tag != "Terrain") {
								flag++;
								wheelBL.brakeTorque = decelerationSpeed;	
								wheelBR.brakeTorque = decelerationSpeed;
								Debug.DrawLine (pos, hit.point, Color.red);
						}
				} else {
						wheelBL.brakeTorque = 0;
						wheelBR.brakeTorque = 0;
				}
				  
				//Front Straight Right Sensor  
				pos += transform.right * frontSensorSideDistance;  
		
				if (Physics.Raycast (pos, transform.forward, out hit, sensorLength)) {  
						if (hit.transform.tag != "Terrain") {  
								flag++;  
								avoidSensitivity -= 1f;   
								Debug.Log ("Avoiding");  
								Debug.DrawLine (pos, hit.point, Color.white);  
						}  
				} else if (Physics.Raycast (pos, rightAngle, out hit, sensorLength)) {  
						if (hit.transform.tag != "Terrain") {  
								avoidSensitivity -= 0.5f;   
								flag++;  
								Debug.DrawLine (pos, hit.point, Color.white);  
						}  
				}

				//Front Straight left Sensor  
				pos = transform.position;  
				pos += transform.forward * frontSensorStartPoint;  
				pos -= transform.right * frontSensorSideDistance;  
		
				if (Physics.Raycast (pos, transform.forward, out hit, sensorLength)) {  
						if (hit.transform.tag != "Terrain") {  
								flag++;  
								avoidSensitivity += 1f;   
								Debug.Log ("Avoiding");  
								Debug.DrawLine (pos, hit.point, Color.white);  
						}  
				} else if (Physics.Raycast (pos, leftAngle, out hit, sensorLength)) {  
						if (hit.transform.tag != "Terrain") {  
								flag++;  
								avoidSensitivity += 0.5f;  
								Debug.DrawLine (pos, hit.point, Color.white);  
						}  
				}

				//Right SideWay Sensor  
				if (Physics.Raycast (transform.position, transform.right, out hit, sidewaySensorLength)) {  
						if (hit.transform.tag != "Terrain") {  
								flag++;  
								avoidSensitivity -= 0.5f;  
								Debug.DrawLine (transform.position, hit.point, Color.white);  
						}  
				}

				//Left SideWay Sensor  
				if (Physics.Raycast (transform.position, -transform.right, out hit, sidewaySensorLength)) {  
						if (hit.transform.tag != "Terrain") {  
								flag++;  
								avoidSensitivity += 0.5f;  
								Debug.DrawLine (transform.position, hit.point, Color.white);  
						}  
				}  

		pos = transform.position;
		pos += transform.forward * frontSensorStartPoint;

				//Front Mid Sensor  
				if (avoidSensitivity == 0) {  
			
						if (Physics.Raycast (pos, transform.forward, out hit, sensorLength)) {  
								if (hit.transform.tag != "Terrain") {  
										if (hit.normal.x < 0) {
												avoidSensitivity = -1;
										} else {
												avoidSensitivity = 1;
										} 
										Debug.DrawLine (pos, hit.point, Color.white);
										
								}  
						}  
				}
				if (flag != 0) {
						AvoidSteer (avoidSensitivity);		
				}
		}

		void AvoidSteer (float sensitivity)
		{
				wheelFL.steerAngle = avoidSpeed * sensitivity;
				wheelFR.steerAngle = avoidSpeed * sensitivity;
		}
}

So when your car starts going left does it log anything? Probably try logging different strings say Front Mid Sensor logs “Front mid” so you can know exactly where is the problem.

You may use this simple Raycasting Script for this problem. Hope it will help.

using UnityEngine;
using System.Collections;

public class Raycasting : MonoBehaviour {
	
	// Update is called once per frame
	void Update () {
		
		
	    Vector3 fside;
		Vector3 rside;
		Vector3 strt;
		fside = transform.position;
		rside = transform.position;
		strt = transform.position;
		
		
		fside.y += .7f;
		rside.y += .7f;
		strt.y += .7f;
		
		
		
//		Vector3 forward = transform.TransformDirection(Vector3.forward) * 5;
		Debug.DrawRay(strt, transform.forward*9, Color.green);
		
		Debug.DrawRay(rside, (transform.forward+transform.right*-.5f)*8, Color.green);
		Debug.DrawRay(fside, (transform.forward+transform.right*.5f)*8, Color.green);
		RaycastHit  hit;
		
		
		if(Physics.Raycast(strt,transform.forward, out hit, 9)) {
			if(hit.collider.gameObject.tag == "Player" || hit.collider.gameObject.tag == "AIBody" || hit.collider.gameObject.tag == "Obstacle"){
				
				transform.Rotate(Vector3.up, 90 * 5* Time.smoothDeltaTime);
				Debug.DrawRay(transform.position, transform.forward, Color.red);
			}
		}
		
		
		
		if(Physics.Raycast(rside,(transform.forward+transform.right*-.5f)*5, out hit, 8)) {
			if(hit.collider.gameObject.tag == "Player" || hit.collider.gameObject.tag == "AIBody" || hit.collider.gameObject.tag == "Obstacle"){
				
				transform.Rotate(Vector3.up, 90 * 2* Time.smoothDeltaTime);
				Debug.DrawRay(transform.position, (transform.forward+transform.right*-.5f)*8, Color.red);
			}
		}
		if(Physics.Raycast(fside,(transform.forward+transform.right*.5f)*5, out hit, 8)) {
			if(hit.collider.gameObject.tag == "Player" || hit.collider.gameObject.tag == "AIBody" || hit.collider.gameObject.tag == "Obstacle"){
				
				transform.Rotate(Vector3.up, -90 * 2* Time.smoothDeltaTime);
				Debug.DrawRay(transform.position , (transform.forward+transform.right*.5f)*8, Color.red);
			}
		}
		
	}
}