A C# script that uses NavMesh for path finding and simulates vehicle movement using unity's physics components
- Setup The Scene
- CarAI Package
- Programming
- Common Issues And How To Fix Them
- Unity 2018 or higher
- NavMeshComponents (This package is different from the built-in NavMesh)
-
CarAI.cs: This is the main script. It's responsible for generating a path using NavMesh and simulating vehicle movement using unity's physics engine
-
controllingCarAI.cs: this script has examples of controlling the AI through code
-
CarAISensor.cs: This script is an example of controlling the AI through Code (It is also useful for creating Traffic system).
Note: It's highly recommended to use the NavMeshComponents package from GitHub rather than the built-in package.
After importing NavMeshComponents into your project, Create an Empty GameObject then "add component" and choose NavMeshSurface.
Then use these settings:
1- Agent Type: Select the Agent type (Or create a new agent with the following settings)
Name: "Car"
Radius: 1.8
Height: 2
Step Height: 1.1
Max Slope: 45Note: These values may differ from one vehicle to another.
2- Collect Objects: All
3- Include Layers: Choose the layer you want the agent to move in. (Create a layer and assign all the roads to it)
4- Use Geometry: I prefer "Render Meshes" but you can use "Physics colliders" as well
Then click on "Bake" and wait for it to finish
After The NavMesh is Backed, A color (purple color) will appear on the street which represents the area where the AI can move (This means that the AI's pivot won't leave this area)
Note: As you see in the image above. The car's center point(pivot) won't leave the purple area(NavMeshSurface). But, if the whole street is purple. The car might move on the sidewalk. To prevent this use NavMesh Modifier to Override all the sidewalks as a Non-Walkable area. Then bake the surface again.
For the CarAI package to work the car model must have these components:
1- Mass: Set the value from 1000 to 1500 (It depends on the vehicle. Ex:A Truck will be 1500)
And you can leave everything else as it is
Note: it's highly recommended to watch this tutorial on wheel colliders
Select all the wheels then "Add component" and choose "Wheel Collider"
Then apply these values(these values may differ according to your scenario):
Note: These values may differ according to the Vehicle type. So, adjust it carefully.
1- Mass: From 80 to 100
2- Radius: Depends on the car model (wheel radius)
2- Wheel Damping Rate: From 0.01 to 1 (Higher value means slower rotation)
3- Spring: 5
4- Damper: 100
5- Target Position: 0.5
3- Forward Friction Stiffness: From 15 to 20
4- Sideways Friction Stiffness: From 7.5 to 10
You need to attach "CarAI.cs" Script to the car. Then Follow these steps:
1- Car Wheels (Wheel collider): Assign each wheel collider to its corresponding location
2- Car Wheels (Transform): Assign each Wheel model to its corresponding object
3- Car Front: Create a new empty GameObject as a child of the vehicle then place this object at the front of the vehicle and assign this Gameobject to
Car Front
Field1- Nav Mesh Layers: Enter the name of the layers you want the AI to move in
2- Max Steering Angle: The Maximum steering angle for the vehicle
3- Max RPM: You can use it to control the speed of the vehicle the lower the value the slower the car
1- Patrol: This is useful for traffic systems as the AI will keep generating a random destination after it reaches the active one.
2- Custom Destination: If a transform is assigned then the AI will keep generating a path to that destination
Note: if both
Patrol
is True andCustom Destination
is assigned, then the AI will keep generating a path to the custom destination. (In Other words,Custom Destination
has priority overPatrol
)1- Show Gizmos: Show the FOV of the AI and wire spheres representing the waypoints of the current path
What is the FOV of the AI?
In unity, the normal AI can turn around, and this behavior can't be applied to cars because they have steering angles. So, I created a field of view for the AI to prevent it from turning more than
Max Steering Angle
Away from his forward position.2- Debugger: Display debugging info in the console
Here are some examples of controlling the AI with scripts
You will find these examples in a script called "controllingCarAI.cs" in the package files
Case 1: The car is not in the NavMesh area
Fix: Never place the car outside the NavMesh area
Case 2: There are no possible paths available
As you see in the image above the AI was able to create a random destination. But, The problem here is the last waypoint
To understand the problem you need to understand how the AI generates a path:
After the AI generates a random destination it checks if the first waypoint is located in the FOV or not. (If not, then the AI will try to generate another path). So, When The AI reaches the final waypoint it will be facing that giant rock. (Like in the image below)
When it tries to generate a path. it will be stuck in a loop of generating a path and refusing it (because it's not in the FOV)
Fix:
(The Best Solution) 1- Change the area type of roads that have sharp turns using the NavMesh Modifier component (And don't forget to add the new area type to the Area Mask in the NavMeshAgent Component). So, The AI can move in this area but can't create destinations in it.
2- Modify the behavior of the AI to move backward if it gets stuck for some time
3- By increasing the FOV: But this is not a great idea because increasing the FOV without increasing the MaxSteering Angle will make the car move in circles around the waypoint.
Anyway if you want to increase the FOV. Open CarAI.cs at line 40 you can change the default value of AIFOV.
The same problem happens when the car reaches a dead end.
Fix: You can fix this by excluding all Dead-Ends from the NavMeshSurface (Using NavMesh Modifier). So, the AI won't go there