On the last video we saw how to make attacks from a distance using projectiles and also how to do some healing
in this video we're finally going to gice our enemies the ability to attack, move around and
we're are also going to be making a simple spawn system for our enemies to be spawned on the scene
and we're going to give our enemies a system to... An alert system so that they can tell their friends
when they spot one of our units, the first thing we have to define to give our enemies some intelligence
is their State Machine, remember that in the case of the units, the movement state was the one with the highest priority
but for the enemies, the combat state is going to be the one with the highest priority
before looking at the scripts that give our enemies their new abilities, let's see a little change that was made to the Root script
remember our TakeDamage() function that we used to deal damage to the units? well now
when the HP reaches zero, instead of directly destroying the object we first check if that object
is one of our units and if it is, we deactivate the unit and use our new KirRevive function
to reactivate that unit with a 5 seconds delay, now our kir revive function just
what it does is just to refill the HP, updates the HP bar and as I said
it reactivates the unit's GameObject. Now the scripts that allow our enemies to attack are pretty much the same scripts
that our units use but with a few differences the first difference is that
they no longer look for the "Orc" tag on the detection list, of course because they need to look for the units
not other enemies and the other difference is that they don't check if
they are not in the movement state before changing to the combat state because as I said
when it comes to enemies, the combat state takes priority over every other state the last difference is that
when they have no more enemies on the detection zone or in this case, when the enemies have no more units
on their detection zone they don't go back to the idle state, they go back to the moving state
and of course the script for our ranged enemies have the same 3 differences, first
the change of the detection tags, second, the change of the state machine conditions
and finally, the state that the unit goes when it is no longer in combat
now let's see how our enemies move around, as you can see, there are now a series of waypoints in our scene
and these are going to serve as the points where the enemies are going to move to
in a certain order, each way point is just a transform witch a sphere collider
and the enemy WayPoint script on it, let's see how it works, we have this little "Orc" right here and when we play the scene
we can see that it goes to the moving state it goes to whatever next way point the first way point tells it to go
and when it reaches the way point it waits for a bit and goes moving again to the final way point
this is the script of our way points, we can see it only has 3 variables so it's really simple
2 booleans to indicate if this is the first way point or the last way point and an array
of possible next way points, in this script we're only going to use the OnTriggerEnter() function
and when an object enters this trigger collider, we check if the tag is "Orc" to see if
the object is one of our enemies, then we check if this way point is marked or is identified as
the last way point, if it is, then we tell that enemy that his next way point is going to be nothing
so we're going to get that enemy moving script which we're going to see in a while
and we're going to access this wayPoint variable that is going to tell the enemy movement script where to go
and we're going to clear that variable, now if this is not the last way point of the system
we're going to select one random way point of our list of next possible way points
and we're going to put this way point on the movement script of the enemy
as it's next way point, the next thing we have to do is to check the state of the enemy to idle
but if this is the first way point of our system we're going to change the state of that enemy
directly to moving, now let's see how the enemy movement script actually works
in the variable we have a reference to the Root of that enemy, a reference to the navMeshAgent component of the enemy
a transform variable to hold the next way point that this enemy is going to move to then we have a
maximum wait time before moving when the enemy reaches a new way point and a boolean variable
that is going to let us know if the enemy is deciding where to go next, this is going to be like a little effect
for our enemies so that when they reach a way point they wait for a bit like if they were deciding where to go next
and then when this maxWaitTime ends they actually move to their next way point
on the initialization of this script we just get the components as usual
the root component and the agent component, now on the Update() of this script, the first thing we have to do is to check
if this enemy is in the movement state, then we check if this enemy has somewhere to go
so if his wayPoint variable is null, then we change this enemy's state to idle
if this enemy has somewhere to go, then we use the agent component to move to the position of that way point
now the next thing this script does is to check if this enemy current state is idle and it does have somewhere to go
and it is not deciding where to go, then this conditional right here first set the deciding boolean to true so
the enemy is deciding where to go then we calculate our waiting time based on our max wait time variable
and we invoke our get moving function with a delay of the waiting time we just calculated
finally, our get moving function changes the state of the unit to moving and sets the deciding variable to false
that's everything the movement system needs to work as you can see our enemies move to the way points
and once they reach the way points they wait a little bit as if they were deciding where to go and then resume their movement
now let's check our enemy spawning system, as you can see we have an enemy spawning object and it spawns enemies in waves of 3
the only thing this enemy spawner object has is our enemy spawner script
in the enemy spawner script the first thing we have is a list of possible enemies that can spawn on this point
then we of course have a time to wait between each wave then we have 2 integers that will help us
count how many orcs have spawned in the current wave and the maximum orcs we will spawn in each wave
then we also have a little waiting time between spawning each enemy and also a variable that will help us
get a little variation between the time of each wave
on the initialization of this script we invoke the SpawnWave() function with a delay of our wave time
and in this spawn wave function the only thing we do is set the wave count to zero, this is how many enemies
have spawned in this wave and we execute the SpawnOrc() function
the first thing we do in the SpawnOrc() function is of course to increment the number of orcs that have been spawned in this wave
then if this number is less or equal to maximum orcs per wave
we select a random orc from our list of orcs to spawn
and we instantiate this new enemy, finally
we invoke this same function with a delay of spawnTime so this is a recursive function that invokes itself
once enough enemies have spawned what we do is to invoke the SpawnWave() function that was the first one we used
with a delay of waitTime plus a little variation that will depend on the waiTimeVariation variable
so the last ability we're going to give our enemies* is the ability to tell other enemies in it's detection zone
that it has detected an Unit, so it can tell all his friends that he has spotted an Unit so that everyone else joins the combat
Let's see this in action, when the first unit comes into this enemy* detection zone
it is going to tell this two enemies*, it is going to alert these two enemies* and this enemy* is going to also alert
this other enemy right here, let's see this happening, the unit comes in the detection zone and everyone gets to combat
this is our enemy alert script, it only has 4 variables, first a reference to the Root script of the enemy
then a transform to keep track of the spotted unit and a vector3 to
have an alert point and a reference to the navMeshAgent component
of the enemy, on the initialization, as usual, we only get the components we need to have
on the Update() the first thing we are going to check is if this enemy is in the combat state
if it is, we are going to do a for each loop with every object in his detection list
if this enemy finds one of our two units in his detection list then it is going to save it's transform in the unit spotted variable
now once we have assigned a transform to our unit spotted variable, then we're going to look for
every other enemy in our detection zone that is not in the combat state
so we can get this same script component in those other enemies and
assign to their alert point variable the position of the unit we have spotted
after that we're going to change that enemy state to the following state
on the enemies, the following state is going to serve as the alert state
now, still in Update() of this script, we're going to check if this enemy is on the following state which is our alert state
if this enemy have been alerted by another enemy we're going to do a for each loop on all the objects
of this detected list, if we find another enemy in the detection list that is not in the combat state
then we're going to communicate that enemy our alert point and we're going to change that enemy state to the following state
you see how this is going? each enemy tells every other that it have been alerted
now if this enemy is far from the alert point position we are going to use the navMeshAgent component to move
near of that alert point and when we get close to that alert point, we're going to change the state of this enemy
to the moving state, and that's it, that's everything we have to do to enable our alert system in our enemies
and that's it, we have seen how to make every single basic mechanic
to make our simple RTS game, so, thanks a lot for watching this video
and if you have any questions leave them in the comments below, good bye =)
hope to see you again soon~
my next unity videos will be about my grad project
but they will be in spanish :P
thanks for watching my first unity tutorials =)
hope they have been helpful to you~
No comments:
Post a Comment