Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Ai car script

Discussion in 'Scripting' started by TurnkeyAgenda24, Jan 22, 2022.

  1. TurnkeyAgenda24

    TurnkeyAgenda24

    Joined:
    Aug 20, 2021
    Posts:
    27
    Hello I am making an arcade style demolition derby game and I was wondering how do I make ai vehicles that randomly chose an other vehicle player or ai and ram into them.
     
  2. Putcho

    Putcho

    Joined:
    Jun 1, 2013
    Posts:
    246
    1. you made a simple foundation idea of 1 ai vehicles and 1 target, and then made ai ram into that target.
    2. solving pathing and collision problem.
    3. after you fully understanding of you first foundation idea then you implement random target select.
     
    GroZZleR likes this.
  3. TurnkeyAgenda24

    TurnkeyAgenda24

    Joined:
    Aug 20, 2021
    Posts:
    27
    do you know any very basic ai car controller scripts?
     
  4. Putcho

    Putcho

    Joined:
    Jun 1, 2013
    Posts:
    246
    its doesnt need to be a car, just a experiment with cube first.
    you can google search unity basic navmesh ai
     
  5. TurnkeyAgenda24

    TurnkeyAgenda24

    Joined:
    Aug 20, 2021
    Posts:
    27
    the standard assets has a ai car controller with waypoints but all the scripts are broken :(
     
  6. TurnkeyAgenda24

    TurnkeyAgenda24

    Joined:
    Aug 20, 2021
    Posts:
    27
    it says no mono behavior scripts in file
    Code (CSharp):
    1. using System;
    2. using UnityEngine;
    3. using Random = UnityEngine.Random;
    4.  
    5.  
    6. namespace UnityStandardAssets.Vehicles.Car
    7. {
    8.     [RequireComponent(typeof (CarController))]
    9.     public class CarAIControl : MonoBehaviour
    10.     {
    11.         public enum BrakeCondition
    12.         {
    13.             NeverBrake,                 // the car simply accelerates at full throttle all the time.
    14.             TargetDirectionDifference,  // the car will brake according to the upcoming change in direction of the target. Useful for route-based AI, slowing for corners.
    15.             TargetDistance,             // the car will brake as it approaches its target, regardless of the target's direction. Useful if you want the car to
    16.                                         // head for a stationary target and come to rest when it arrives there.
    17.         }
    18.  
    19.         // This script provides input to the car controller in the same way that the user control script does.
    20.         // As such, it is really 'driving' the car, with no special physics or animation tricks to make the car behave properly.
    21.  
    22.         // "wandering" is used to give the cars a more human, less robotic feel. They can waver slightly
    23.         // in speed and direction while driving towards their target.
    24.  
    25.         [SerializeField] [Range(0, 1)] private float m_CautiousSpeedFactor = 0.05f;               // percentage of max speed to use when being maximally cautious
    26.         [SerializeField] [Range(0, 180)] private float m_CautiousMaxAngle = 50f;                  // angle of approaching corner to treat as warranting maximum caution
    27.         [SerializeField] private float m_CautiousMaxDistance = 100f;                              // distance at which distance-based cautiousness begins
    28.         [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!)
    29.         [SerializeField] private float m_SteerSensitivity = 0.05f;                                // how sensitively the AI uses steering input to turn to the desired direction
    30.         [SerializeField] private float m_AccelSensitivity = 0.04f;                                // How sensitively the AI uses the accelerator to reach the current desired speed
    31.         [SerializeField] private float m_BrakeSensitivity = 1f;                                   // How sensitively the AI uses the brake to reach the current desired speed
    32.         [SerializeField] private float m_LateralWanderDistance = 3f;                              // how far the car will wander laterally towards its target
    33.         [SerializeField] private float m_LateralWanderSpeed = 0.1f;                               // how fast the lateral wandering will fluctuate
    34.         [SerializeField] [Range(0, 1)] private float m_AccelWanderAmount = 0.1f;                  // how much the cars acceleration will wander
    35.         [SerializeField] private float m_AccelWanderSpeed = 0.1f;                                 // how fast the cars acceleration wandering will fluctuate
    36.         [SerializeField] private BrakeCondition m_BrakeCondition = BrakeCondition.TargetDistance; // what should the AI consider when accelerating/braking?
    37.         [SerializeField] private bool m_Driving;                                                  // whether the AI is currently actively driving or stopped.
    38.         [SerializeField] private Transform m_Target;                                              // 'target' the target object to aim for.
    39.         [SerializeField] private bool m_StopWhenTargetReached;                                    // should we stop driving when we reach the target?
    40.         [SerializeField] private float m_ReachTargetThreshold = 2;                                // proximity to target to consider we 'reached' it, and stop driving.
    41.  
    42.         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)
    43.         private CarController m_CarController;    // Reference to actual car controller we are controlling
    44.         private float m_AvoidOtherCarTime;        // time until which to avoid the car we recently collided with
    45.         private float m_AvoidOtherCarSlowdown;    // how much to slow down due to colliding with another car, whilst avoiding
    46.         private float m_AvoidPathOffset;          // direction (-1 or 1) in which to offset path to avoid other car, whilst avoiding
    47.         private Rigidbody m_Rigidbody;
    48.  
    49.  
    50.         private void Awake()
    51.         {
    52.             // get the car controller reference
    53.             m_CarController = GetComponent<CarController>();
    54.  
    55.             // give the random perlin a random value
    56.             m_RandomPerlin = Random.value*100;
    57.  
    58.             m_Rigidbody = GetComponent<Rigidbody>();
    59.         }
    60.  
    61.  
    62.         private void FixedUpdate()
    63.         {
    64.             if (m_Target == null || !m_Driving)
    65.             {
    66.                 // Car should not be moving,
    67.                 // use handbrake to stop
    68.                 m_CarController.Move(0, 0, -1f, 1f);
    69.             }
    70.             else
    71.             {
    72.                 Vector3 fwd = transform.forward;
    73.                 if (m_Rigidbody.velocity.magnitude > m_CarController.MaxSpeed*0.1f)
    74.                 {
    75.                     fwd = m_Rigidbody.velocity;
    76.                 }
    77.  
    78.                 float desiredSpeed = m_CarController.MaxSpeed;
    79.  
    80.                 // now it's time to decide if we should be slowing down...
    81.                 switch (m_BrakeCondition)
    82.                 {
    83.                     case BrakeCondition.TargetDirectionDifference:
    84.                         {
    85.                             // the car will brake according to the upcoming change in direction of the target. Useful for route-based AI, slowing for corners.
    86.  
    87.                             // check out the angle of our target compared to the current direction of the car
    88.                             float approachingCornerAngle = Vector3.Angle(m_Target.forward, fwd);
    89.  
    90.                             // also consider the current amount we're turning, multiplied up and then compared in the same way as an upcoming corner angle
    91.                             float spinningAngle = m_Rigidbody.angularVelocity.magnitude*m_CautiousAngularVelocityFactor;
    92.  
    93.                             // if it's different to our current angle, we need to be cautious (i.e. slow down) a certain amount
    94.                             float cautiousnessRequired = Mathf.InverseLerp(0, m_CautiousMaxAngle,
    95.                                                                            Mathf.Max(spinningAngle,
    96.                                                                                      approachingCornerAngle));
    97.                             desiredSpeed = Mathf.Lerp(m_CarController.MaxSpeed, m_CarController.MaxSpeed*m_CautiousSpeedFactor,
    98.                                                       cautiousnessRequired);
    99.                             break;
    100.                         }
    101.  
    102.                     case BrakeCondition.TargetDistance:
    103.                         {
    104.                             // the car will brake as it approaches its target, regardless of the target's direction. Useful if you want the car to
    105.                             // head for a stationary target and come to rest when it arrives there.
    106.  
    107.                             // check out the distance to target
    108.                             Vector3 delta = m_Target.position - transform.position;
    109.                             float distanceCautiousFactor = Mathf.InverseLerp(m_CautiousMaxDistance, 0, delta.magnitude);
    110.  
    111.                             // also consider the current amount we're turning, multiplied up and then compared in the same way as an upcoming corner angle
    112.                             float spinningAngle = m_Rigidbody.angularVelocity.magnitude*m_CautiousAngularVelocityFactor;
    113.  
    114.                             // if it's different to our current angle, we need to be cautious (i.e. slow down) a certain amount
    115.                             float cautiousnessRequired = Mathf.Max(
    116.                                 Mathf.InverseLerp(0, m_CautiousMaxAngle, spinningAngle), distanceCautiousFactor);
    117.                             desiredSpeed = Mathf.Lerp(m_CarController.MaxSpeed, m_CarController.MaxSpeed*m_CautiousSpeedFactor,
    118.                                                       cautiousnessRequired);
    119.                             break;
    120.                         }
    121.  
    122.                     case BrakeCondition.NeverBrake:
    123.                         break;
    124.                 }
    125.  
    126.                 // Evasive action due to collision with other cars:
    127.  
    128.                 // our target position starts off as the 'real' target position
    129.                 Vector3 offsetTargetPos = m_Target.position;
    130.  
    131.                 // if are we currently taking evasive action to prevent being stuck against another car:
    132.                 if (Time.time < m_AvoidOtherCarTime)
    133.                 {
    134.                     // slow down if necessary (if we were behind the other car when collision occured)
    135.                     desiredSpeed *= m_AvoidOtherCarSlowdown;
    136.  
    137.                     // and veer towards the side of our path-to-target that is away from the other car
    138.                     offsetTargetPos += m_Target.right*m_AvoidPathOffset;
    139.                 }
    140.                 else
    141.                 {
    142.                     // no need for evasive action, we can just wander across the path-to-target in a random way,
    143.                     // which can help prevent AI from seeming too uniform and robotic in their driving
    144.                     offsetTargetPos += m_Target.right*
    145.                                        (Mathf.PerlinNoise(Time.time*m_LateralWanderSpeed, m_RandomPerlin)*2 - 1)*
    146.                                        m_LateralWanderDistance;
    147.                 }
    148.  
    149.                 // use different sensitivity depending on whether accelerating or braking:
    150.                 float accelBrakeSensitivity = (desiredSpeed < m_CarController.CurrentSpeed)
    151.                                                   ? m_BrakeSensitivity
    152.                                                   : m_AccelSensitivity;
    153.  
    154.                 // decide the actual amount of accel/brake input to achieve desired speed.
    155.                 float accel = Mathf.Clamp((desiredSpeed - m_CarController.CurrentSpeed)*accelBrakeSensitivity, -1, 1);
    156.  
    157.                 // add acceleration 'wander', which also prevents AI from seeming too uniform and robotic in their driving
    158.                 // i.e. increasing the accel wander amount can introduce jostling and bumps between AI cars in a race
    159.                 accel *= (1 - m_AccelWanderAmount) +
    160.                          (Mathf.PerlinNoise(Time.time*m_AccelWanderSpeed, m_RandomPerlin)*m_AccelWanderAmount);
    161.  
    162.                 // calculate the local-relative position of the target, to steer towards
    163.                 Vector3 localTarget = transform.InverseTransformPoint(offsetTargetPos);
    164.  
    165.                 // work out the local angle towards the target
    166.                 float targetAngle = Mathf.Atan2(localTarget.x, localTarget.z)*Mathf.Rad2Deg;
    167.  
    168.                 // get the amount of steering needed to aim the car towards the target
    169.                 float steer = Mathf.Clamp(targetAngle*m_SteerSensitivity, -1, 1)*Mathf.Sign(m_CarController.CurrentSpeed);
    170.  
    171.                 // feed input to the car controller.
    172.                 m_CarController.Move(steer, accel, accel, 0f);
    173.  
    174.                 // if appropriate, stop driving when we're close enough to the target.
    175.                 if (m_StopWhenTargetReached && localTarget.magnitude < m_ReachTargetThreshold)
    176.                 {
    177.                     m_Driving = false;
    178.                 }
    179.             }
    180.         }
    181.  
    182.  
    183.         private void OnCollisionStay(Collision col)
    184.         {
    185.             // detect collision against other cars, so that we can take evasive action
    186.             if (col.rigidbody != null)
    187.             {
    188.                 var otherAI = col.rigidbody.GetComponent<CarAIControl>();
    189.                 if (otherAI != null)
    190.                 {
    191.                     // we'll take evasive action for 1 second
    192.                     m_AvoidOtherCarTime = Time.time + 1;
    193.  
    194.                     // but who's in front?...
    195.                     if (Vector3.Angle(transform.forward, otherAI.transform.position - transform.position) < 90)
    196.                     {
    197.                         // the other ai is in front, so it is only good manners that we ought to brake...
    198.                         m_AvoidOtherCarSlowdown = 0.5f;
    199.                     }
    200.                     else
    201.                     {
    202.                         // we're in front! ain't slowing down for anybody...
    203.                         m_AvoidOtherCarSlowdown = 1;
    204.                     }
    205.  
    206.                     // both cars should take evasive action by driving along an offset from the path centre,
    207.                     // away from the other car
    208.                     var otherCarLocalDelta = transform.InverseTransformPoint(otherAI.transform.position);
    209.                     float otherCarAngle = Mathf.Atan2(otherCarLocalDelta.x, otherCarLocalDelta.z);
    210.                     m_AvoidPathOffset = m_LateralWanderDistance*-Mathf.Sign(otherCarAngle);
    211.                 }
    212.             }
    213.         }
    214.  
    215.  
    216.         public void SetTarget(Transform target)
    217.         {
    218.             m_Target = target;
    219.             m_Driving = true;
    220.         }
    221.     }
    222. }
    223.