This time we go through tanks navigation system.
The source code for this project is available on my github :
AITank.cs
All tanks inherit variables some methods from BaseTank.cs, AITank is made to have much more functionality than PlayerTank.cs to make it autonomous.
The AI uses a generated Navigation Mesh to traverse the world :
Unity's Nav Mesh System has several useful built-in functions to supply the AI with the information it needs to go around the nav-mesh, more on that later.
I needed a couple of things in mind. The AI needs to roam around and look for a target. While than happens it needs to do a few things :
Check Radius : How often the AI looks around themselves for enemies.
Perimeter Check Frequency : How often the AI perform this check.
This is what some of that looks like in code:
[Tooltip("How far should we look for enemies?")]
[SerializeField] float m_CheckRadius = 100.00F;
[Tooltip("How often should this tank check for surrounding enemies?")]
[SerializeField] float m_PerimeterCheckFrequency = 3;
Keeps track of several other variables
Vector3 m_TargetDestination;
Vector3 m_DestinationAlongPath;
Vector3 m_PositionAtStartOfReverse;
private int m_IndexAlongPath = 0;
private NavMeshPath m_NavMeshPath;
private readonly List<Vector3> m_WayPoints = new();
m_TargetDestination is where the AI's desired location is. This is changed dynamically.
While the AI is looking around for enemies, they will roam randomly. The random roaming implementation is quite simple actually.
private void DoRandomRoaming()
{
if (!m_HasDestination)
{
m_HasStartedAlongThePath = false;
//Get a random position in the level...
m_TargetDestination = new()
{
x = Random.Range(-250, 250),
y = 0,
z = Random.Range(-250, 250)
};
CheckIfTargetDestinationIsValid(m_TargetDestination);
}
else
{
TravelAlongPath();
m_IsCheckingForEnemies = true;
}
}
In short it checks whether or not it has a place to go, if it doesn't, it throws a flag saying it hasn't started on a path along the destination. It will get a random position within the bounds of the level, in this example these values are hardcoded. The Y position is zero-ed out to keep the random position on the ground. The AI then checks if the target destination is valid.
In this method, we use the NavMesh's Sample Position to check if the target destination is actually on the nav mesh. After that we calculate a path and because we have a path we throw two flags, we have a destination and we have started along the path.
Don't mind that comment I forgot to remove it. The NavMesh class comes in clutch again and has a build in method for calculating a path to a target destination. thiswill return a NavMeshPath which contains an array of Vector3's called "corners". A corner in this context is a point along the path, I store these in a List of vector3's.
After all this is done, the AI will "TravelAlongPath()", in this method the AI basically moves from where it is to the next checkpoint along the path, the problem with this is the distance from centre of the AI's transform and the AI checkpoint position must be exactly zero before moving on to the next checkpoint, fortunately a simple way around this is to give the AI a minimum distance before moving on to the next checkpoint, this way it doesn't have to be right on top of the checkpoint before moving on.
That's about all I can say about this unless...you have very specific questions and I'll get right into it in another blog. Please let me know down below.
コメント