Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

navmesh and A.I car doubts.

Discussion in 'Scripting' started by pauloaguiar, Apr 23, 2015.

  1. pauloaguiar

    pauloaguiar

    Joined:
    May 13, 2009
    Posts:
    700
    I have doubts about the navMesh for AI cars
    I do not understand that the new standard assents had been an example of how to use navMesh an AI car. But now no longer well with these examples in version 5.
    I do not understand why the navMesh was only created for the use of characters, and not supported for vehicles?
    If the navemesh give to use in the vehicle, would like to see a tutorial on how to use the navMesh in vehicles.
    I think it would be more valuable to use navMesh in vehicles that use waypoints. at least it is guaranteed that the vehicle runs on different paths of the track.

    I hope this help topic to navMesh solution in vehicles and coding.
    I don´t know if this is the right place to add this post.
     
  2. cl9-2

    cl9-2

    Joined:
    May 31, 2013
    Posts:
    417
    @duck had a proof-of-concept NavMesh AI Car, in this video



    I believe the basic idea is that vehicle chases a NavMesh Agent that is following the waypoints along the track.
     
    Vaibhav98, MayhemMike and pauloaguiar like this.
  3. cl9-2

    cl9-2

    Joined:
    May 31, 2013
    Posts:
    417
    Maybe it's possible to add a feature request for Wheel Colliders to support NavMesh paths.
     
    Lethn likes this.
  4. pauloaguiar

    pauloaguiar

    Joined:
    May 13, 2009
    Posts:
    700
    Cool. I hope and see if they made wheelcollider support for navMesh.
    in my opinion is better that using way points, and the A.I can drive in multiple ways on the rood i mean different road.
     
  5. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
    havnt tried it in U5, but all my vehicles use navmeshagent in U4 fine.
     
  6. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,462
    You don't need WheelCollider support for NavMesh, you need to design an AI that looks like a car.

    Navmesh doesn't care if its a character, a car, or a space narwhal.
     
    Lethn and JamesLeeNZ like this.
  7. pauloaguiar

    pauloaguiar

    Joined:
    May 13, 2009
    Posts:
    700
    Yes the navMesh, does not affect anything besides having the navMesh Agent at its bluish way.


    I go to try recreate an test scene and simple car and track with 2 paths to start create the logic of the navMesh Agent and simple car A.I follow the agent and steering.
    The only question i have is how do i put the navMesh Agent moving in loop in the track. I will see it.
     
  8. cl9-2

    cl9-2

    Joined:
    May 31, 2013
    Posts:
    417
    Not quite. Wheel colliders don't adjust themselves to a NavMesh agent's rotation, nor does the agent's speed and acceleration map directly to a wheel collider's motorTorque, which is why a script is needed to convert the agent's desired velocity into the appropriate wheel angle and motorTorque for a wheel collider. The AI must be designed for a car to follow or chase after a NavMesh agent.

    Do you mean, a loop, where once it reaches the last point it starts from the beginning point?

    Or do you mean a vertical loop?

     
    bostonvaulter and pauloaguiar like this.
  9. pauloaguiar

    pauloaguiar

    Joined:
    May 13, 2009
    Posts:
    700

    Yes, once it reaches the last point it starts from the beginning point, normal tracks racing.
     
  10. cl9-2

    cl9-2

    Joined:
    May 31, 2013
    Posts:
    417
    You would want something to the effect of:
    Code (CSharp):
    1. void Update () {
    2.  
    3.         if (Vector3.Distance(agent.transform.position, waypoints[currentWaypoint].position) < threshold)
    4.         {
    5.      
    6.             currentWaypoint++;
    7.      
    8.             if (currentWaypoint == waypoints.Count)
    9.                 currentWaypoint = 0;
    10.          
    11.             /* Alternatively:
    12.             currentWaypoint = (currentWaypoint + 1) % waypoints.Count;
    13.             */
    14.          
    15.             agent.SetDestination(waypoints[currentWaypoint].position);
    16.         }
    17.  
    18.     }
    where you have class members such as:
    Code (CSharp):
    1. private NavMeshAgent agent;
    2. private int currentWaypoint;
    3. private List<Transform> waypoints;
    4. public float threshold = 15f;
     
  11. pauloaguiar

    pauloaguiar

    Joined:
    May 13, 2009
    Posts:
    700
    I create an simple unity package, it have simple road and walls , simple car. all made in cinema 4D. the road is navMesh baked. the car have simple player driver controller. ready for play around whit navmesh / agent and vehicle testing.
     

    Attached Files:

  12. cl9-2

    cl9-2

    Joined:
    May 31, 2013
    Posts:
    417
    I'll take a look. Would you have a version of the track that includes waypoint markers, preferably with each waypoint marker having orientation information?
     
  13. pauloaguiar

    pauloaguiar

    Joined:
    May 13, 2009
    Posts:
    700
    Yes that is what i have now in the A.I
    I keep changing it, trying new things, but I can share all the script and waypoint. Some parts based on youtube tutorials.

    Any better A.I car script fixing correction let me know.
     

    Attached Files:

  14. cl9-2

    cl9-2

    Joined:
    May 31, 2013
    Posts:
    417
    Several Hints:
    • You want to attach an agent to an AI vehicle, which is aligned to the AI vehicle's position at each update loop (by setting agent's localPosition to (0,0,0) ).
    • The agent's destination should be each successive waypoint along the track. Once the agent is within a certain distance of a target waypoint, you can set it to the next waypoint (see above code).
    • The vehicle chases the agent's next position with the velocity vector. The agent's desired Velocity property provides this velocity vector, but it has to be transformed into the AI vehicle's coordinate system, then converted into percentage of torque and wheel Angle.
    • For avoidance to work obstacles must be able to be carved into the Navmesh.
     
    ZiadJ likes this.
  15. pauloaguiar

    pauloaguiar

    Joined:
    May 13, 2009
    Posts:
    700
    tks for the reply. It seen to many logic.

    I reached a conclusion that the navMesh and navmesh Agent, was not made for such things as vehicle. Something tells me the Vehicle behavior results is not favorable. I think I'll give up this method.
    perhaps a future unity team create a navMesh Agent exclusively for vehicles., perhaps as navMesh Agent Vahicle.
    Either way it could be that I'm wrong.
     
  16. cl9-2

    cl9-2

    Joined:
    May 31, 2013
    Posts:
    417
    That's generally correct, Unity's NavMesh system is not well-designed for physics controlled objects interacting with other physics controlled objects. It's better to use ray casts, and have AI vehicles react to obstacles' positions and velocities using ray casts.
     
  17. pauloaguiar

    pauloaguiar

    Joined:
    May 13, 2009
    Posts:
    700
    Tks.
     
  18. duck

    duck

    Unity Technologies

    Joined:
    Oct 21, 2008
    Posts:
    358
    This is exactly the method I used in the video clip mentioned above. You can also set the Agent's acceleration value to zero, meaning that it cannot move itself - but it still has the desiredVelocity property that you can read. It's this "desired velocity" that you can make use of to create any kind of AI pathfinding vehicle or character, when you want to use the pathfinding aspect of the navmesh, but don't want the navmesh agent's style of motion.
     
    metroidsnes and cl9-2 like this.
  19. pauloaguiar

    pauloaguiar

    Joined:
    May 13, 2009
    Posts:
    700
    Ok, tks for the reply.
     
  20. MayhemMike

    MayhemMike

    Joined:
    Oct 23, 2013
    Posts:
    51
    I'm currently playing around with this concept and in connection with the Standard Assets AI script I'm using steeringtarget to set my own Waypointtarget object, which seems to do the job in my example scene with 4 cars on the track. Although I'm curious how duck combined the navmeshagent with the waypoint system in the video. Does it just use the waypoints as agent destinations or does it also incorporate other elements like the ProgressTracker.

    My biggest problem at this point is that the agents sometimes drive off the track as if there was an invisible roundabout next to the real track. Not sure what's causing that, I suspect it has something to do with the agent coming in contact with a different navmesh-cost-area but not sure.
     
  21. pauloaguiar

    pauloaguiar

    Joined:
    May 13, 2009
    Posts:
    700
    That is the problem whit the Agent collisions, if you create an combat car racing like , Destruction Derby, Carmaggedom ,Demolition Derby, FlatOut series, WipeOut series etc...
    the physics behavior reacts glitchy and bad physics collisions etc....
    For that reason i give up continue with this method.
     
  22. pauloaguiar

    pauloaguiar

    Joined:
    May 13, 2009
    Posts:
    700
    There is an interesting A.I behavior scripting in Carmaggedom OpenC1 C#, an guy recreate an Stainless engine.
    probably convert the Opponents A.I behavior scripts to the unity , i don´t know just an idea.
     
  23. MayhemMike

    MayhemMike

    Joined:
    Oct 23, 2013
    Posts:
    51
    I'm using it for a standard racing game so it should (hopefully) do the trick. Since my last post I tried to visualize the agents desired path and do some debugging on top of it. Turns out that sometimes the object with the navmeshagent wanders off from its origin which caused part of the weird behavior. And sometimes the pathfinding is just a tick too late which gives the car a point that it already has passed and causing it to turn around.

    Did you have a look at the Apex path finding system? Depending on the layout of your tracks the grid based system might do the trick for your game
     
  24. pauloaguiar

    pauloaguiar

    Joined:
    May 13, 2009
    Posts:
    700
    For now i stay in waypoints, because is crash racing:)
     
  25. cl9-2

    cl9-2

    Joined:
    May 31, 2013
    Posts:
    417
    At each update, the NavMesh agent should stay with the origin of the AI vehicle, with the acceleration property set to 0. You'll probably want to create a separate class that sets the agent's destination to each waypoint, and also converts the agent's desired Velocity into acceleration, brake, and torque parameters for CarController.move.
     
    ZiadJ likes this.
  26. cliu10

    cliu10

    Joined:
    May 11, 2017
    Posts:
    3
    @cl-9 I am trying to process what you mentioned above. Is the script you mentioned above goes into Navmesh agent movement script? I was trying to incorporate the script, but shows "Field `MoveTo.waypoints' is never assigned to, and will always have its default value `null'". Can you help me with it? Thank you.

    Code (CSharp):
    1. // MoveTo.cs
    2. using UnityEngine;
    3. using System.Collections;
    4. using UnityEngine.AI;
    5. using System.Collections.Generic;
    6.  
    7.  
    8. public class MoveTo : MonoBehaviour {
    9.  
    10.     public Transform goal;
    11.     private NavMeshAgent agent;
    12.     private int currentWaypoint;
    13.     Private List<Transform> Waypoints;
    14.     public float threshold = 15f;
    15.  
    16.  
    17.     void Start () {
    18.         NavMeshAgent agent = GetComponent<NavMeshAgent>();
    19.         agent.destination = goal.position;
    20.     }
    21.  
    22.     void Update () {
    23.  
    24.         if (Vector3.Distance(agent.transform.position, Waypoints[currentWaypoint].position) < threshold)
    25.         {
    26.  
    27.             currentWaypoint++;
    28.  
    29.             if (currentWaypoint == Waypoints.Count)
    30.                 currentWaypoint = 0;
    31.  
    32.             /* Alternatively:
    33.             currentWaypoint = (currentWaypoint + 1) % waypoints.Count;
    34.             */
    35.  
    36.             agent.SetDestination(Waypoints[currentWaypoint].position);
    37.         }
    38.  
    39.     }
    40. }
     
  27. cl9-2

    cl9-2

    Joined:
    May 31, 2013
    Posts:
    417
    You'll want to populate the waypoints variable using code similar to this:

    Code (CSharp):
    1. void  GetWaypoints (){
    2.         Transform[] potentialWaypoints = waypointContainer.GetComponentsInChildren< Transform >();
    3.         waypoints = new List<Transform> ();
    4.      
    5.         foreach( Transform potentialWaypoint in potentialWaypoints ) {
    6.             if ( potentialWaypoint != waypointContainer.transform ) {
    7.                 waypoints.Add (potentialWaypoint);
    8.          
    9.             }
    10.         }
    11.     }
    The above code assumes that you've declared waypointContainer in the MoveTo class
    Code (CSharp):
    1. public GameObject waypointContainer;
     
  28. Bloke28

    Bloke28

    Joined:
    Apr 23, 2017
    Posts:
    3
    Thanks guys above for all you help, Its definitely do-able, now to tweak for faster cars racing. But this so far will do for any on-coming traffic.
     
  29. qwertyuaezakmi

    qwertyuaezakmi

    Joined:
    Jun 29, 2017
    Posts:
    1
    Hey bloke could you please give me this unity package I need to make an Ai setup like this
     
  30. dreek16designer

    dreek16designer

    Joined:
    Mar 21, 2020
    Posts:
    8
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. public class Opponent : MonoBehaviour
    5. {
    6.     public WheelCollider[] FrontWheels;
    7.     public WheelCollider[] BackWheels;
    8.     private Transform Target;
    9.     public float maxSteerAngle = 35f;
    10.     public float maxTorque = 500f;
    11.     void Update()
    12.     {
    13.    
    14.     }
    15.     private void OnTriggerEnter(Collider other)
    16.     {
    17.         if (other.GetComponent<WheelDrive>())
    18.         {
    19.             WheelDrive car = other.GetComponent<WheelDrive>();
    20.             if (car.GetComponent<Rigidbody>().velocity.z <= 10)
    21.             {
    22.                 Target = car.transform;
    23.                 foreach(WheelCollider wheel in FrontWheels)
    24.                 {
    25.                     float distance = Vector3.Distance(transform.position, car.transform.position);
    26.                     float angle = maxSteerAngle * distance;
    27.                     wheel.steerAngle = angle;
    28.                 }
    29.                 foreach(WheelCollider wheel in BackWheels)
    30.                 {
    31.                     if (Target != null)
    32.                     {
    33.                         float distance = Vector3.Distance(transform.position, car.transform.position);
    34.                         float torque = maxTorque * distance;
    35.                         wheel.motorTorque = torque;
    36.                     }
    37.                 }
    38.             }
    39.         }
    40.     }
    41.     private void OnCollisionEnter(Collision collision)
    42.     {
    43.         if (collision.collider.GetComponent<WheelDrive>())
    44.         {
    45.             WheelDrive car = collision.collider.GetComponent<WheelDrive>();
    46.             if (car.GetComponent<Rigidbody>().velocity.z == 10)
    47.             {
    48.                 Target = car.transform;
    49.                 foreach (WheelCollider wheel in FrontWheels)
    50.                 {
    51.                     wheel.transform.LookAt(Target);
    52.                 }
    53.                 foreach (WheelCollider wheel in BackWheels)
    54.                 {
    55.                     if (Target != null)
    56.                     {
    57.                         float distance = Vector3.Distance(transform.position, car.transform.position);
    58.                         float torque = maxTorque * distance;
    59.                         wheel.motorTorque = torque;
    60.                     }
    61.                 }
    62.             }
    63.         }
    64.     }
    65. }
    Is the code I'm using but without nav mesh agent. It respond to player speeding
     
  31. dreek16designer

    dreek16designer

    Joined:
    Mar 21, 2020
    Posts:
    8
    Actually, I figured out an error with the steering. It doesn't work
     
  32. sushanta1991

    sushanta1991

    Joined:
    Apr 3, 2011
    Posts:
    305