Version: 2020.2

# Important Classes - Vectors

Vectors are a fundamental mathmatical concept which allow you to describe a direction and magnitude. In games and apps, vectors are often used describe some of the fundamental properties such as the position of a character, the speed something is moving, or the distance between two objects.

Vector arithmetic is fundamental to many aspects of computer programming such as graphics, physics and animation, and it is useful to understand it in depth to get the most out of Unity.

Vectors can be expressed in multiple dimensions, and Unity provides the Vector2, Vector3 and Vector4 classes for working with 2D, 3D, and 4D vectors. These three types of Vector classes all share many of the same functions, such as magnitude, so most of the information on this page applies to all three types of Vector unless otherwise specified.

This page provides an overview of the Vector classes and their common uses when scripting with them. For an exhaustive reference of every member of the vector classes, see the script reference pages for Vector2, Vector3 and Vector4.

## Understanding Vector Arithmetic

`````` var pointInAir = pointOnGround + new Vector2(0, 5);
``````

Although the examples here show 2D vectors, the same concept applies to 3D and 4D vectors.

### Subtraction

``````// 矢量 d 的大小与 c 相同，但指向相反的方向。
var c = b - a;
var d = a - b;

``````

``````// 这两者得出相同的结果。
var c = a - b;
var c = a + -b;

``````

## Direction and Distance from One Object to Another

``````// 获取从玩家位置指向目标位置的矢量。
var heading = target.position - player.position;

``````

As well as pointing in the direction of the target object, this vector’s magnitude is equal to the distance between the two positions. You may need a “normalized” vector giving the direction to the target, but with a fixed distance (say for directing a projectile). You can normalize a vector by dividing it by its own magnitude:

``````var distance = heading.magnitude;
var direction = heading / distance; // This is now the normalized direction.
``````

``````if (heading.sqrMagnitude < maxRange * maxRange) {
// 目标在范围内。
}
``````

Sometimes, when working in 3D, you might need an “overground heading” to a target. For example, imagine a player standing on the ground who needs to approach a target floating in the air. If you subtract the player’s position from the target’s then the resulting vector will point upwards towards the target. This is not suitable for orienting the player’s transform since they will also point upwards; what is really needed is a vector from the player’s position to the position on the ground directly below the target. You can obtain this by taking the result of the subtraction and setting the Y coordinate to zero:-

``````var heading = target.position - player.position;
``````

## Dot Product

Below you can see a comparison of how vectors of varying angles compared with a reference vector return a dot product value between 1 and –1 :

The dot product is a mathematically simpler operation than calculating the cosine, so it can be used in place of the Mathf.Cos function or the vector magnitude operation in some circumstances (it doesn’t do exactly the same thing but sometimes the effect is equivalent). However, calculating the dot product function takes much less CPU time and so it can be a valuable optimization.

The dot product is useful if you want to calculate the amount of one vector’s magnitude that lies in the direction of another vector.

For example, a car’s speedometer typically works by measuring the rotational speed of the wheels. The car may not be moving directly forward (it may be skidding sideways, for example) in which case part of the motion will not be in the direction the car is facing - and so won’t be measured by the speedometer. The magnitude of an object’s rigidbody.velocity vector will give the speed in its direction of overall motion but to isolate the speed in the forward direction, you should use the dot product:

``````var fwdSpeed = Vector3.Dot(rigidbody.velocity, transform.forward);
``````

## Cross Product

The cross product is only meaningful for 3D vectors. It takes two 3D vectors as input and returns another 3D vector as its result.

The result vector is perpendicular to the two input vectors. You can use the “left hand rule” to remember the direction of the output vector from the ordering of the input vectors. If the first parameter is matched up to the thumb of the hand and the second parameter to the forefinger, then the result will point in the direction of the middle finger. If the order of the parameters is reversed then the resulting vector will point in the exact opposite direction but will have the same magnitude.

The cross product can seem complicated since it combines several useful pieces of information in its return value. However, like the dot product, it is very efficient mathematically and can be used to optimize code that would otherwise depend on slower transcendental functions such as sine and cosine.

## Computing a Normal/Perpendicular vector

A “normal” vector (ie. a vector perpendicular to a plane) is required frequently during mesh generation and is also useful in path following and other situations. Given three points in the plane, say the corner points of a mesh triangle, you can find the normal as follows: - Pick one of the three points - Subtract it from each of the two other points separately (resulting in two new vectors, “Side 1” and “Side 2”) - Calculate the cross product of the vectors “Side 1” and “Side 2” - The result of the cross product is a new vector that is perpendicular to the plane the three original points lie on - the “normal”.

``````Vector3 a;
Vector3 b;
Vector3 c;

Vector3 side1 = b - a;
Vector3 side2 = c - a;

Vector3 normal = Vector3.Cross(side1, side2);
``````

The “left hand rule” can be used to decide the order in which the two vectors should be passed to the cross product function. As you look down at the top side of the surface (from which the normal will point outwards) the first vector should sweep around clockwise to the second:

``````float perpLength = perp.magnitude;
perp /= perpLength;
``````

Another useful note is that the area of the triangle is equal to perpLength / 2. This is useful if you need to find the surface area of the whole mesh or want to choose triangles randomly with probability based on their relative areas.