In this lecture, I'd like you to follow along as we examine moving along a straight line using vectors.
So download the resource project that comes with this lecture. In there you'll find a Man/character
and on top of that is being added a Move script and it's the Move script that we're going to be working
in.
So open that up and have a look in here.
You can see in the script that there is a Vector3 which is a goal.
So the Vector3 is a 3D version of our vector which has an x, y and z and we're initially setting
that vector to be 5 in the x-direction, 0 in the y-direction and 4 in the z-direction. Because
this is a humanoid character on a flat surface,
when we move him around, we're not adding any 'y' because you don't want him to go up and float in the
air.
If it was an airplane or something that flies it would be completely different.
Notice also there's no physics whatsoever involved in this project.
We're moving this character purely using our own code and that's so that we can keep control of it.
Now in the Start function, we're adding our Vector3 onto the current position of our character.
So here we've got a transform and we're running a Translate.
What that does is it adds the 'goal vector' to the 'transform vector'. With that saved, go back to
Unity and press Play.
And what you'll see is your character jump 'that much distance' along that vector. Because it's in the
Start function,
it's adding the whole lot at once and moving your character to that goal.
Now that's not going to work
if you want to move the character bit-by-bit in the Update and make it appear as though it's moving
itself. So stop playing. Let's go back into Move and have a look at moving this Translate down
into the Update.
Get rid of the one from the Start and save that, switch back into Unity and press Play.
And what you'll notice is the character completely disappears, but if you select the Man in the Hierarchy,
have a look at the transform and the position in the x and the z are going up and up and up and that's
because that whole vector is being added each time an update occurs.
So he is moving, he's just jumping in very big leaps and getting further and further away so that
we can't see him. So let's stop that.
What we want, instead of jumping to the goal position, is to move in little tiny steps along here, in exactly
the same direction as that vector.
So to get a smaller version of the vector, you can divide the larger vector by a number that will give be something
littler.
So if we just go back into Move and in the Start, let's go
goal = goal * 0.5f; and that's going to halve the size of the goal.
So now he should move along the same direction,
but you should see him stop halfway along and then jump to the goal location.
But after that he will keep cycling and adding the goal on. Save that, switch back to Unity, press Play.
You probably saw him jump a little bit there and that was him moving in those steps, still a big leap but
only half of the vector each time.
So let's go back into Move.
What happens if we multiply this by 0.01, so we get 10% of that vector instead.
Anything you multiply or divide on the vector is going to still be in exactly the same direction that
you want your character to go.
So let's play this one, have a look.
So that's much smoother in the movement and he's moving towards the goal location.
Now the goal location itself wasn't a position in space.
It was a 'goal direction'.
So there's a difference between a point and a vector. A point is a fixed spot somewhere in your world.
A vector is just a set of instructions of which direction to move in, from any location in your world.
So your character is now somewhere, if you click on him, still moving along at 10% of 'goal' each
time.
Now if we simply multiply 'our vector we want our character to move along' by a small number, then
whenever that vector changes, it's going to affect our characters speed.
He won't be moving at a constant speed and we can illustrate that by adding in another character.
So first of all let's make our vector goal public, so that we can change it, then we will still multiply
it by 0.01 and translate along that.
So just save that.
Now if we go back into Unity, get the Man and just Ctrl-D to duplicate and then move him out and
try and put him moving in this direction, we want them to move parallel to each other.
So I just want to put it him there.
But for this guy, his move goal, let's multiply it up by 2.
So it's twice as far away.
It's out here somewhere.
So let's make that 10, 0 and
8.
So now when we run it, we'll see different speeds. see how this guy's going much faster because
10% of that longer vector is going to be a bigger jump than 10% of the shorter.
So they're not at a uniform speed and that's going to make the movement of your character inconsistent
when they're moving along different length vectors.
So the question is how can we get a vector
that is a standard size, that points in the same direction along the vector that we're traveling along.
The solution is to get its 'Normalized' version. The normalized version of any vector is a vector that
is 1 in length and you can find the normalized version of a vector by dividing each of the x, y and
z values of the vector by the magnitude.
Now you can also get Unity to do it for you.
Let's go back into the Move and instead of having our goal here that we're moving along multiplied by
0.01 just to make it much smaller, we want to make it into a standard size.
So let's just get rid of that altogether
and what we're trying to do is translate along goal.normalized...like that and that will be a vector
of unit length 1 going in the same direction.
Now when you play, this will probably be too far.
So if we just come back and run it. Yes, you can see that they did move at the same rate
but it was quite jittery and it was a big hop each update.
But we now know that we have a standardized unit 1 movement each update and now that we have this,
we can multiply this by a speed value to change how fast our character is going.
So let's just create another 'public float speed' and we'll set that (because we want
to make it a bit slower) 0.1f and then multiply your normalized goal by your speed...like that
and now because it's public, you could change the speed for each of those characters but we'll just leave
it 0.1 for both of them because we want to see them moving at the same rate. Press Play...
and there you go...and they'll go on for ever and ever
because even though we gave them starting vectors that were completely different, they were pointing
in the same direction
and then they got normalized down to unit 1
and so they ended up with exactly the same vector multiplied by exactly the same speed.
So it doesn't matter how long the vector is, if you normalize it, you end up with the same little vector
which is of unit 1.
Now those speeds, even though you think it's a consistent speed, the other factor involved in it (go back
into your move code) is the speed at which this Update occurs because every time your game runs an update
it's not necessarily at exactly the same time that the last update happened.
So you will get inconsistencies in the speed and although you probably won't even notice these, you will
see in a lot of code that people multiply by Time.deltaTime
and what this does is it smooths out and allows for the difference in the update running.
The other thing I should say too before we finish up, is to make this a LateUpdate.
Any movement you've got on your characters (and especially when you start to add cameras that
follow things around) you'll want it all to happen
after all the physics has been calculated in the scene.
Currently we don't have physics so it's not an issue, but you should get into the habit of putting your
movements into LateUpdate, which I still am not and feel free to correct me throughout,
if I do have an update loop with movement in it because I'm bound to, because that's a bad habit of mine.
So this should be all we need now to have a nice smooth and consistent movement of our character.
Save it. Let's go back into Unity and press Play...
...and now...
well that speed's quite small, isn't it?
You can say that the multiplying of the Time.deltaTime has also slowed it down a fair bit because
it's going to be quite a tiny value because of the time difference between update loops and therefore
that allows you to then play around with the speeds that you're setting on your characters. So maybe
instead of 0.1, you might want to change these to 1 and try it out.
That's a bit better but that really is the code you should use when you stop moving a character around.
All right so that's it for moving something in a straight line and how to get consistent speed in your
character's movements. In the next lecture,
we will start to look at moving towards a goal and making our characters turn.