Unity : AI [Navmesh implementation (Part IV)]
Ok, we need to fix the little bug we had in the previous article.
Let’s explain what the problem is :
After we reach every points, the code try to search for another point which don’t exist, so we have an ArgumentOutOfRangeException.
A simple way to fix it is to create a check :
if we are at the last point, restart from the first point.
In the code we make this change :
In few words, if we are at the last point, go back to first.
In the else statement, we simply need to add 1 to our currentPoint
So we have an If / Else Statement :
if we are at the last point, we restart from the first point,
if not, _currentPoint++
And out of this check, we need to pass the “movement”
If we test it now
It works, BUT we have an error.
And the error is, again, ArgumentOutOfRangeException.
NOTE : Even if we talk about IA and NavMesh, I’m take one moment to explain a little thing about collections in programming. Because I have see a lot of people have problems with this logic, (me too at the beginning!) and at the end is more easy than you think.
The point is this : every time we use a collection (Array, List, etc) we have to remember one simple thing : the first element is at 0 INDEX.
Now, .Length or .Count, returns how many elements are in the collection.
It means that if we have an Array of 5 elements,
.Length RETURNS 5, NOT 4.
And in this case, for example, _currentPoint represent the INDEX.
So when we arrive at the end and check if :
_currentPoint == _points.Count,
_currentPoint is 5 BUT _point.Count is 6
and 6 DOES NOT EXIST, because we have only 5 indexs.
And that’s why we have this error -> OUT OF THE BOUND OF THE LIST<>.
To fix this error, we have to check if _currentPoint (index 5) is equal to 5, not 6.
And we know that 5 is 6 - 1
Everything now works fine and we don’t have any errors.
If we want to make AI move faster, we can do it thanks to
NavMesh Agent component -> Speed
Now, this works good and it’s fine, but if we want to create a logic to move in reverse order when we reach the end?
The logic, in pseudo code, is :
when we arrive at last point, move in reverse so it do not restart form point, but back to point, then point etc.
One way to do it is to create a bool variable isReverse, and in the If Statement we add this lines of code
What happen here is when we are at the last point, we go back to point.
Obviously we don’t have yet the full logic implementation, so with this code we move from point to point, but then we are stuck in an infinite loop from point to point and vice versa.
This because when we are point we set next point to point, and when we are in the point we set next destination to point.
What we try to do is to have two different logic, one moves linear and one in reverse, and make the code modular so we can decide what type of logic we need to run.
How can we do this?
We already have the bool with which we can decide if we move linear or the other way around right?
And we use it to make the first check :
we move linear or we move in reverse?
To check if we are at the end we can use the same code we had before
This because : when we use the reverse logic?
When we are at the end of the path right?
So when we are at point, isReverse == true, and we start to decrement _currentPoint, but if we are not at the end, we need to increase _currentPoint to make AI move until teh end of the path.
With this implementation, everything works until we are at the point, then is Reverse == true and we go back to point, but inside the If (isReverse) we don’t have nothing yet so the AI stop.
To manage the logic inside here, we need to check what?
First, if we are at the beginning.
Because we need to go back until we are at the beginning and at the moment we are at point.
This is easy to do
And waht happen where we are at the beginning?
isReverse == false and we need to increment currentPoint again.
But if we aren’t at the beginning, we need to move toward the point.
So in the else, we set currentPoint- -
We test it
This is how we manage a simple AI with a bunch of If/Else Statement, and at the end od the days this is how works an AI, many If/Else to take decisions.
If we want clean up the code a bit, we can divide in methods (and this is the best practice), one for Forward and one for Reverse (we simply create the method and cut and paste the code)
And we do the same for tha last piece inside Update()
In the next article we start to talk to another incredible topic about AI :
the FSM or Finite State Machine!