In this episode we're going to be looking at the Vector structs, which we use to store
things like: positions, velocities and directions.
When we're working in 3 dimensional space, we need three values to define a vector - one
for the x axis, one for the y, and one for the z. This is called a Vector3. When we're
working in 2D space and no longer require the z axis, we can switch to using a vector2
Let's take a brief look at vectors. Say I define a Vector2 with an x value of -4 and
a y value of 3. The usual definition of a Vector states it as a quantity having direction
as well as magnitude, or in other terms, length. We can calculate this magnitude using the
theorem of Pythagoras: so in this case the magnitude is equal to the sqrt(-4^2 + 3^2);
which is 5. To calculate the direction of the vector, we have to normalize it. To do
this we just have to divide both the x and y values by the magnitude: so -4/5 = -.8,
and 3/5 = .6; The significance of what we've just done is that, if we calculate the magnitude
of this direction: sqrt(-.8^2 + .6^2); we'll get a value of 1.
As a practical example of why this is important, say we create a vector2 from the player's
input. Imagine the player is holding down the left and up key, so we have an input vector
(-1;1). Now say we want to move the player object a distance of 3 units in that direction,
so we multiply this input vector by 3, giving us (-3;3). We then move the player object
-3 units on the x axis, and 3 units on the y axis. But, if we measure the distance the
player has moved, we can see it is about 4.2, instead of the 3 we intended. The mistake
we've made has allowed the player to travel faster when moving diagonally. And its an
easy mistake to make, so remember, if you want to treat a vector as a direction, normalize
it first. I find it helpful to think of a normalized vector as fitting perfectly inside
of a unit circle. Our unnormalized input vector with a value of (-1; 1), clearly lies outside
the circle, whereas if we normalize it by dividing it by its magnitude - that being
root(2) - it will have a value of approximately (-.71;.71).
Now because vectors conveniently define an x, y, and potentially z value, we use them
in programming to define, not only directions and velocities, but also simply a point in
space. Say we have a vector representing the current
position of the player object at (-4;1), and then another vector representing the position
of an enemy object over here at maybe (2;3). Now if we were to subtract the enemy's position
from the player's, we'd end up with a new vector of (-6; -2). Considering this new vector
as a position would be quite meaningless, however considered as the displacement between
the player and the enemy, it can be very useful. Its magnitude is the distance between the
two, and if we normalize it, we get the direction from the enemy towards the player. Both of
these, of course, are very useful to be able to calculate.
The vector structs - Vector2, Vector3, and even Vector4 - already exist as part of the
unity library, which we are given access to by the line 'using UnityEngine' at the top
of our code. All the same, we're going to be creating our own rudimentary version of
the Vector3 struct, just so we have a better understanding of what's going on when we use
Vectors in our code.
Now you might be wondering what a struct actually is. Structs are similar to classes, in that
they act as a container for some code. There are some important differences between the
two, but we're going to worry about those in a later episode. I like to think of structs
as a way of grouping related variables together to form a single, custom variable type. Say
for example we have an Enemy class, which needs to keep track of a vector for its current
velocity, and a vector for the position the target its chasing. We could have six float
variables: 3 defining the velocity, and 3 defining the target's position. By creating
a vector struct, however, which groups together these x, y, and z floats, any time we need
to represent a set of 3 numbers, we can simply use this custom Vector variable.
Inside the vector struct would be a bit of code called the constructor. We'll talk about
this in detail when we look at structs properly, later on the series. But this basically enables
us to set the values inside the vector by writing = new Vector3(3,4,5);
We can also get or set the values of the x y and z axes individually by writing, for
example, velocity.x = 5; Unity's implementation of the vector structs
also contain handy methods for doing things like getting the magnitude of a vector, or
the normalized value of a vector.
As a last note, I would like to talk about what sort of operations are defined for vectors.
We can multiply a vector by a number, which has the effect of multiplying each of the
individual axes by that number. The same goes for division.
We can also add two vectors together, which simply adds the like axes together. x + x,
y +y and so on. The same applies with subtratction. These are the only basic operations that are
defined for Unity's vector structs. Multiply or divide a vector by a number, and add or
subtract two vectors. Fancier operations like the dot and cross product, we will discuss
in a later video.
For now, we've learned some of the basics about vectors and how they are represented
in Unity, so next video we will be able to use this knowledge to do cool things like,
make a cube move around our game world, and have a sphere chase after it. I'll see you