In this lecture, we'll see how we can implement
the very rudimentary artificial intelligence or A.I in our game.
Now we'll make the game harder by adding a little bit of
rudimentary artificial intelligence to the TeddyBearand the TeddyBearProjectile.
So, one of the great things about the components system in
Unity is that if I look at the TeddyBear prefab,
we can see that I've added a Homing Component to the TeddyBear.
And if we look at the TeddyBearProjectile,
we can see I've have added a Homing Component there as well.
So this component based system that Unity has is awesome because we
can add the same component to multiple GameObjects.
Prefabs in this case,
to apply that same behavior to both of them.
Let's actually go take a look at that Homing script.
The Homing Component script has a burger GameObject,
a RigidBody2D, an impulseForce,
a homingDelay, and a homingTimer.
So when the GameObject that the script is attached to gets added to the scene,
we do a number of things.
First, we find the burger and save it.
And we do that because we're going to keep chasing the burger,
and we don't want to have to look up the burger GameObject every time.
The next thing we do,
is we call a GethomingDelay method in ConfigurationUtils to actually get the homingDelay.
We pass in our tag because the homingDelay for
TeddyBear is different from the homingDelay for TeddyBearProjectiles.
And this get a homingDelay method knows how to deal with both of those things.
Finally, we get the RigidBody2D because we're
going to manipulate that as we run our game.
We also create and start our homingTimer.
So we add the component.
Set the homingDelay, add a listener for when the timer is finished,
and start running the timer.
We will see who calls the SetImpulseForce method soon.
But the purpose of this method is to make sure that when a TeddyBear or
TeddyBearProjectile decides to change direction to chase after the burger,
that it stays moving at the same speed it was originally moving at.
We don't want the TeddyBearProjectile say,
to speed up each time it changes
direction because we're adding more force to the RigidBody.
We want to keep it at the same speed.
And so, if we keep track of what
the initial impulseForce was for that particular GameObject,
we can keep it at the same speed even when we change direction.
When the homingTimer finishes,
it's time to actually go toward the burger again.
Our first step is to stop moving and we do
that by setting the RigidBody's velocity to zero.
It's fairly unusual to actually manipulate the velocity of a RigidBody directly.
Usually, we just let the physics system handle everything but in this particular case,
it makes perfect sense because we want to keep the GameObject the script is attached to,
moving at the same speed.
Now, we calculate a vector to that point from here to the burger.
And then we normalize it to make it a unit vector and then we add force to
the RigidBody using the direction we just calculated and the impulseForce that we saved.
So this is the impulseForce that was originally used to get this GameObject moving.
So, because it stopped.
applying that magnitude of impulseForce will get it
moving again at the same speed it was moving up before and then,
we start the homingTimer again so that when it goes off,
we can move toward the burger again.
I promised we'd see who calls SetImpulseForce.
So, if I right click and find references,
we can see the TeddyBear calls it right here,
just after it has calculated the force here to get its RigidBody moving.
It gets the Homing Component that's attached to the same GameObject and sends that
force.magnitude in to the SetImpulseForce method so that it can get saved.
The TeddyBearProjectile does a very similar thing.
Although this time it doesn't actually have to save
it because the TeddyBearProjectile ImpulseForce
is a configuration data item so we can just get it from ConfigurationUtils.
It's not random.
TeddyBearprojectiles always move at the same speed even though TeddyBear actually move at
some random speed that's determined by the MinImpulseForce
and MaxImpulseForce that we generate for the magnitude of that ImpulseForce.
And that's how we add rudimentary A.I to our TeddyBears and our TeddyBearProjectiles.
To recap, in this lecture,
we saw how we can make TeddyBears and TeddyBearProjectiles smarter.
We were reminded of how cool the Unity component system is because we could attach
the same behavior to two distinct GameObjects and in this particular case,
using a Homing Component was a much better solution than using inheritance.
Inheritance is awesome and I use it all the time in my game development,
but in this particular case,
adding a component was the better choice.