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.
@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.
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.
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.
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.
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?
You would want something to the effect of: Code (CSharp): void Update () { if (Vector3.Distance(agent.transform.position, waypoints[currentWaypoint].position) < threshold) { currentWaypoint++; if (currentWaypoint == waypoints.Count) currentWaypoint = 0; /* Alternatively: currentWaypoint = (currentWaypoint + 1) % waypoints.Count; */ agent.SetDestination(waypoints[currentWaypoint].position); } } where you have class members such as: Code (CSharp): private NavMeshAgent agent; private int currentWaypoint; private List<Transform> waypoints; public float threshold = 15f;
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.
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?
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.
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.
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.
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.
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.
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.
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.
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.
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
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.
@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): // MoveTo.cs using UnityEngine; using System.Collections; using UnityEngine.AI; using System.Collections.Generic; public class MoveTo : MonoBehaviour { public Transform goal; private NavMeshAgent agent; private int currentWaypoint; Private List<Transform> Waypoints; public float threshold = 15f; void Start () { NavMeshAgent agent = GetComponent<NavMeshAgent>(); agent.destination = goal.position; } void Update () { if (Vector3.Distance(agent.transform.position, Waypoints[currentWaypoint].position) < threshold) { currentWaypoint++; if (currentWaypoint == Waypoints.Count) currentWaypoint = 0; /* Alternatively: currentWaypoint = (currentWaypoint + 1) % waypoints.Count; */ agent.SetDestination(Waypoints[currentWaypoint].position); } } }
You'll want to populate the waypoints variable using code similar to this: Code (CSharp): void GetWaypoints (){ Transform[] potentialWaypoints = waypointContainer.GetComponentsInChildren< Transform >(); waypoints = new List<Transform> (); foreach( Transform potentialWaypoint in potentialWaypoints ) { if ( potentialWaypoint != waypointContainer.transform ) { waypoints.Add (potentialWaypoint); } } } The above code assumes that you've declared waypointContainer in the MoveTo class Code (CSharp): public GameObject waypointContainer;
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.
Code (CSharp): using System.Collections; using System.Collections.Generic; using UnityEngine; public class Opponent : MonoBehaviour { public WheelCollider[] FrontWheels; public WheelCollider[] BackWheels; private Transform Target; public float maxSteerAngle = 35f; public float maxTorque = 500f; void Update() { } private void OnTriggerEnter(Collider other) { if (other.GetComponent<WheelDrive>()) { WheelDrive car = other.GetComponent<WheelDrive>(); if (car.GetComponent<Rigidbody>().velocity.z <= 10) { Target = car.transform; foreach(WheelCollider wheel in FrontWheels) { float distance = Vector3.Distance(transform.position, car.transform.position); float angle = maxSteerAngle * distance; wheel.steerAngle = angle; } foreach(WheelCollider wheel in BackWheels) { if (Target != null) { float distance = Vector3.Distance(transform.position, car.transform.position); float torque = maxTorque * distance; wheel.motorTorque = torque; } } } } } private void OnCollisionEnter(Collision collision) { if (collision.collider.GetComponent<WheelDrive>()) { WheelDrive car = collision.collider.GetComponent<WheelDrive>(); if (car.GetComponent<Rigidbody>().velocity.z == 10) { Target = car.transform; foreach (WheelCollider wheel in FrontWheels) { wheel.transform.LookAt(Target); } foreach (WheelCollider wheel in BackWheels) { if (Target != null) { float distance = Vector3.Distance(transform.position, car.transform.position); float torque = maxTorque * distance; wheel.motorTorque = torque; } } } } } } Is the code I'm using but without nav mesh agent. It respond to player speeding
Just in case if anyone looking for a navmesh based ai car solution then please check below link, I have tried to implement all the suggestions and discussion mentioned above into a simple project file. https://sushanta1991.blogspot.com/2020/10/ai-car-with-navmesh-agent-unity.html