- Home /
Car AI Help
I'm having problem with some of my cars starting at different times even though they have the script. they should all start at the same time after the countdown also I dont know why some don't follow the path markers.
this is my project if someone wants to take a look at it im trying to get Go Lart AI 1,2 & 3 working from the scene RaceKartz (not RaceKartz1) https://www.dropbox.com/s/ed9c6q19477k5rk/Race%20Karts%20AI%20Help%2013.10.2017.unitypackage?dl=0
The ai script is just from the standard asset pack
using Random = UnityEngine.Random;
namespace UnityStandardAssets.Vehicles.Car
{
[RequireComponent(typeof (CarController))]
public class CarAIControl : MonoBehaviour
{
public enum BrakeCondition
{
NeverBrake, // the car simply accelerates at full throttle all the time.
TargetDirectionDifference, // the car will brake according to the upcoming change in direction of the target. Useful for route-based AI, slowing for corners.
TargetDistance, // the car will brake as it approaches its target, regardless of the target's direction. Useful if you want the car to
// head for a stationary target and come to rest when it arrives there.
}
// This script provides input to the car controller in the same way that the user control script does.
// As such, it is really 'driving' the car, with no special physics or animation tricks to make the car behave properly.
// "wandering" is used to give the cars a more human, less robotic feel. They can waver slightly
// in speed and direction while driving towards their target.
[SerializeField] [Range(0, 1)] private float m_CautiousSpeedFactor = 0.05f; // percentage of max speed to use when being maximally cautious
[SerializeField] [Range(0, 180)] private float m_CautiousMaxAngle = 50f; // angle of approaching corner to treat as warranting maximum caution
[SerializeField] private float m_CautiousMaxDistance = 100f; // distance at which distance-based cautiousness begins
[SerializeField] private float m_CautiousAngularVelocityFactor = 30f; // how cautious the AI should be when considering its own current angular velocity (i.e. easing off acceleration if spinning!)
[SerializeField] private float m_SteerSensitivity = 0.05f; // how sensitively the AI uses steering input to turn to the desired direction
[SerializeField] private float m_AccelSensitivity = 0.04f; // How sensitively the AI uses the accelerator to reach the current desired speed
[SerializeField] private float m_BrakeSensitivity = 1f; // How sensitively the AI uses the brake to reach the current desired speed
[SerializeField] private float m_LateralWanderDistance = 3f; // how far the car will wander laterally towards its target
[SerializeField] private float m_LateralWanderSpeed = 0.1f; // how fast the lateral wandering will fluctuate
[SerializeField] [Range(0, 1)] private float m_AccelWanderAmount = 0.1f; // how much the cars acceleration will wander
[SerializeField] private float m_AccelWanderSpeed = 0.1f; // how fast the cars acceleration wandering will fluctuate
[SerializeField] private BrakeCondition m_BrakeCondition = BrakeCondition.TargetDistance; // what should the AI consider when accelerating/braking?
[SerializeField] private bool m_Driving; // whether the AI is currently actively driving or stopped.
[SerializeField] private Transform m_Target; // 'target' the target object to aim for.
[SerializeField] private bool m_StopWhenTargetReached; // should we stop driving when we reach the target?
[SerializeField] private float m_ReachTargetThreshold = 2; // proximity to target to consider we 'reached' it, and stop driving.
private float m_RandomPerlin; // A random value for the car to base its wander on (so that AI cars don't all wander in the same pattern)
private CarController m_CarController; // Reference to actual car controller we are controlling
private float m_AvoidOtherCarTime; // time until which to avoid the car we recently collided with
private float m_AvoidOtherCarSlowdown; // how much to slow down due to colliding with another car, whilst avoiding
private float m_AvoidPathOffset; // direction (-1 or 1) in which to offset path to avoid other car, whilst avoiding
private Rigidbody m_Rigidbody;
private void Awake()
{
// get the car controller reference
m_CarController = GetComponent<CarController>();
// give the random perlin a random value
m_RandomPerlin = Random.value*100;
m_Rigidbody = GetComponent<Rigidbody>();
}
private void FixedUpdate()
{
if (m_Target == null || !m_Driving)
{
// Car should not be moving,
// use handbrake to stop
m_CarController.Move(0, 0, -1f, 1f);
}
else
{
Vector3 fwd = transform.forward;
if (m_Rigidbody.velocity.magnitude > m_CarController.MaxSpeed*0.1f)
{
fwd = m_Rigidbody.velocity;
}
float desiredSpeed = m_CarController.MaxSpeed;
// now it's time to decide if we should be slowing down...
switch (m_BrakeCondition)
{
case BrakeCondition.TargetDirectionDifference:
{
// the car will brake according to the upcoming change in direction of the target. Useful for route-based AI, slowing for corners.
// check out the angle of our target compared to the current direction of the car
float approachingCornerAngle = Vector3.Angle(m_Target.forward, fwd);
// also consider the current amount we're turning, multiplied up and then compared in the same way as an upcoming corner angle
float spinningAngle = m_Rigidbody.angularVelocity.magnitude*m_CautiousAngularVelocityFactor;
// if it's different to our current angle, we need to be cautious (i.e. slow down) a certain amount
float cautiousnessRequired = Mathf.InverseLerp(0, m_CautiousMaxAngle,
Mathf.Max(spinningAngle,
approachingCornerAngle));
desiredSpeed = Mathf.Lerp(m_CarController.MaxSpeed, m_CarController.MaxSpeed*m_CautiousSpeedFactor,
cautiousnessRequired);
break;
}
case BrakeCondition.TargetDistance:
{
// the car will brake as it approaches its target, regardless of the target's direction. Useful if you want the car to
// head for a stationary target and come to rest when it arrives there.
// check out the distance to target
Vector3 delta = m_Target.position - transform.position;
float distanceCautiousFactor = Mathf.InverseLerp(m_CautiousMaxDistance, 0, delta.magnitude);
// also consider the current amount we're turning, multiplied up and then compared in the same way as an upcoming corner angle
float spinningAngle = m_Rigidbody.angularVelocity.magnitude*m_CautiousAngularVelocityFactor;
// if it's different to our current angle, we need to be cautious (i.e. slow down) a certain amount
float cautiousnessRequired = Mathf.Max(
Mathf.InverseLerp(0, m_CautiousMaxAngle, spinningAngle), distanceCautiousFactor);
desiredSpeed = Mathf.Lerp(m_CarController.MaxSpeed, m_CarController.MaxSpeed*m_CautiousSpeedFactor,
cautiousnessRequired);
break;
}
case BrakeCondition.NeverBrake:
break;
}
// Evasive action due to collision with other cars:
// our target position starts off as the 'real' target position
Vector3 offsetTargetPos = m_Target.position;
// if are we currently taking evasive action to prevent being stuck against another car:
if (Time.time < m_AvoidOtherCarTime)
{
// slow down if necessary (if we were behind the other car when collision occured)
desiredSpeed *= m_AvoidOtherCarSlowdown;
// and veer towards the side of our path-to-target that is away from the other car
offsetTargetPos += m_Target.right*m_AvoidPathOffset;
}
else
{
// no need for evasive action, we can just wander across the path-to-target in a random way,
// which can help prevent AI from seeming too uniform and robotic in their driving
offsetTargetPos += m_Target.right*
(Mathf.PerlinNoise(Time.time*m_LateralWanderSpeed, m_RandomPerlin)*2 - 1)*
m_LateralWanderDistance;
}
// use different sensitivity depending on whether accelerating or braking:
float accelBrakeSensitivity = (desiredSpeed < m_CarController.CurrentSpeed)
? m_BrakeSensitivity
: m_AccelSensitivity;
// decide the actual amount of accel/brake input to achieve desired speed.
float accel = Mathf.Clamp((desiredSpeed - m_CarController.CurrentSpeed)*accelBrakeSensitivity, -1, 1);
// add acceleration 'wander', which also prevents AI from seeming too uniform and robotic in their driving
// i.e. increasing the accel wander amount can introduce jostling and bumps between AI cars in a race
accel *= (1 - m_AccelWanderAmount) +
(Mathf.PerlinNoise(Time.time*m_AccelWanderSpeed, m_RandomPerlin)*m_AccelWanderAmount);
// calculate the local-relative position of the target, to steer towards
Vector3 localTarget = transform.InverseTransformPoint(offsetTargetPos);
// work out the local angle towards the target
float targetAngle = Mathf.Atan2(localTarget.x, localTarget.z)*Mathf.Rad2Deg;
// get the amount of steering needed to aim the car towards the target
float steer = Mathf.Clamp(targetAngle*m_SteerSensitivity, -1, 1)*Mathf.Sign(m_CarController.CurrentSpeed);
// feed input to the car controller.
m_CarController.Move(steer, accel, accel, 0f);
// if appropriate, stop driving when we're close enough to the target.
if (m_StopWhenTargetReached && localTarget.magnitude < m_ReachTargetThreshold)
{
m_Driving = false;
}
}
}
private void OnCollisionStay(Collision col)
{
// detect collision against other cars, so that we can take evasive action
if (col.rigidbody != null)
{
var otherAI = col.rigidbody.GetComponent<CarAIControl>();
if (otherAI != null)
{
// we'll take evasive action for 1 second
m_AvoidOtherCarTime = Time.time + 1;
// but who's in front?...
if (Vector3.Angle(transform.forward, otherAI.transform.position - transform.position) < 90)
{
// the other ai is in front, so it is only good manners that we ought to brake...
m_AvoidOtherCarSlowdown = 0.5f;
}
else
{
// we're in front! ain't slowing down for anybody...
m_AvoidOtherCarSlowdown = 1;
}
// both cars should take evasive action by driving along an offset from the path centre,
// away from the other car
var otherCarLocalDelta = transform.InverseTransformPoint(otherAI.transform.position);
float otherCarAngle = Mathf.Atan2(otherCarLocalDelta.x, otherCarLocalDelta.z);
m_AvoidPathOffset = m_LateralWanderDistance*-Mathf.Sign(otherCarAngle);
}
}
}
public void SetTarget(Transform target)
{
m_Target = target;
m_Driving = true;
}
Then I added cubes as markers and another box as the trackerand itchanges to the next marker once it gets to the first marker.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Dreamcar01Track : MonoBehaviour {
public GameObject TheMarker;
public GameObject Mark01;
public GameObject Mark02;
public GameObject Mark03;
public GameObject Mark04;
public GameObject Mark05;
public GameObject Mark06;
public GameObject Mark07;
public GameObject Mark08;
public GameObject Mark09;
public GameObject Mark10;
public GameObject Mark11;
public GameObject Mark12;
public GameObject Mark13;
public GameObject Mark14;
public GameObject Mark15;
public GameObject Mark16;
public GameObject Mark17;
public GameObject Mark18;
public GameObject Mark19;
public GameObject Mark20;
public GameObject Mark21;
public GameObject Mark22;
public GameObject Mark23;
public GameObject Mark24;
public GameObject Mark25;
public GameObject Mark26;
public GameObject Mark27;
public GameObject Mark28;
public GameObject Mark29;
public GameObject Mark30;
public GameObject Mark31;
public GameObject Mark32;
public GameObject Mark33;
public int MarkTracker;
void Update () {
if (MarkTracker == 0) {
TheMarker.transform.position = Mark01.transform.position;
}
if (MarkTracker == 1) {
TheMarker.transform.position = Mark02.transform.position;
}
if (MarkTracker == 2) {
TheMarker.transform.position = Mark03.transform.position;
}
if (MarkTracker == 3) {
TheMarker.transform.position = Mark04.transform.position;
}
if (MarkTracker == 4) {
TheMarker.transform.position = Mark05.transform.position;
}
if (MarkTracker == 5) {
TheMarker.transform.position = Mark06.transform.position;
}
if (MarkTracker == 6) {
TheMarker.transform.position = Mark07.transform.position;
}
if (MarkTracker == 7) {
TheMarker.transform.position = Mark08.transform.position;
}
if (MarkTracker == 8) {
TheMarker.transform.position = Mark09.transform.position;
}
if (MarkTracker == 9) {
TheMarker.transform.position = Mark10.transform.position;
}
if (MarkTracker == 10) {
TheMarker.transform.position = Mark11.transform.position;
}
if (MarkTracker == 11) {
TheMarker.transform.position = Mark12.transform.position;
}
if (MarkTracker == 12) {
TheMarker.transform.position = Mark13.transform.position;
}
if (MarkTracker == 13) {
TheMarker.transform.position = Mark14.transform.position;
}
if (MarkTracker == 14) {
TheMarker.transform.position = Mark15.transform.position;
}
if (MarkTracker == 15) {
TheMarker.transform.position = Mark16.transform.position;
}
if (MarkTracker == 16) {
TheMarker.transform.position = Mark17.transform.position;
}
if (MarkTracker == 17) {
TheMarker.transform.position = Mark18.transform.position;
}
if (MarkTracker == 18) {
TheMarker.transform.position = Mark19.transform.position;
}
if (MarkTracker == 19) {
TheMarker.transform.position = Mark20.transform.position;
}
if (MarkTracker == 20) {
TheMarker.transform.position = Mark21.transform.position;
}
if (MarkTracker == 21) {
TheMarker.transform.position = Mark22.transform.position;
}
if (MarkTracker == 22) {
TheMarker.transform.position = Mark23.transform.position;
}
if (MarkTracker == 23) {
TheMarker.transform.position = Mark24.transform.position;
}
if (MarkTracker == 24) {
TheMarker.transform.position = Mark25.transform.position;
}
if (MarkTracker == 25) {
TheMarker.transform.position = Mark26.transform.position;
}
if (MarkTracker == 26) {
TheMarker.transform.position = Mark27.transform.position;
}
if (MarkTracker == 27) {
TheMarker.transform.position = Mark28.transform.position;
}
if (MarkTracker == 28) {
TheMarker.transform.position = Mark29.transform.position;
}
if (MarkTracker == 29) {
TheMarker.transform.position = Mark30.transform.position;
}
if (MarkTracker == 30) {
TheMarker.transform.position = Mark31.transform.position;
}
if (MarkTracker == 31) {
TheMarker.transform.position = Mark32.transform.position;
}
if (MarkTracker == 32) {
TheMarker.transform.position = Mark33.transform.position;
}
}
IEnumerator OnTriggerEnter(Collider collision) {
if (collision.gameObject.tag == "Dreamcar01") {
this.GetComponent<BoxCollider> ().enabled = false;
MarkTracker += 1;
if (MarkTracker == 32) {
MarkTracker = 1;
}
yield return new WaitForSeconds (1);
this.GetComponent<BoxCollider> ().enabled = true;
}
}
}
so I add that script to track and add all the markers to it
I has mothing to do with my countdown timer code because they are moving at random times even before i made that code.
Your answer
Follow this Question
Related Questions
Car collision impact with object 1 Answer
Give Car Direction Using Single Touch 1 Answer
Wheels Are Too Much Inward 0 Answers
Can I make my car move forward only and without inputs? 1 Answer
car and controller 1 Answer