Vector Length / Vector Length XY / Normalize¶
At a glance
Lives in: Kismet Math Library; Blueprint API / Math / Vector -
Returns: Vector Length and Vector Length XY return a real number;
Normalize returns a Vector - none can return None -
Fails by: Normalize returns (0, 0, 0) when the input is too small
for its squared-length tolerance; the length nodes return 0 for a zero
vector -
Official docs: Vector Length,
Vector Length XY,
and Normalize
The one-minute version¶
- A vector contains an amount on three axes. Length turns that vector into one non-negative scalar: its magnitude.
Vector Lengthuses X, Y, and Z.Vector Length XYignores Z.Get Velocity->Vector Length XYis the usual ground-speed calculation. Use full length for flight, swimming, projectiles, or any other genuinely 3D motion.Normalizekeeps the direction but changes a safely large vector to length1. It removes the original distance or speed.- A zero or near-zero vector has no dependable direction.
Normalizereturns(0, 0, 0)when the input's squared length is below its tolerance. - To find direction from A to B, subtract first, then normalize:
Normalize(B - A). - Use a squared-length node for threshold comparisons when you do not need the actual distance. Compare it with the threshold squared.
- Normalizing a raw analog-stick vector makes almost every nonzero input full strength. Preserve or clamp analog magnitude when partial input matters.
What each node returns¶
For A = (X, Y, Z), the operations have these shapes:
Vector Length(A) = sqrt(X*X + Y*Y + Z*Z)
Vector Length XY(A) = sqrt(X*X + Y*Y)
Normalize(A) = A / Vector Length(A), when A is safely large
Examples:
| Input | Vector Length |
Vector Length XY |
Normalize |
|---|---|---|---|
(3, 4, 0) |
5 |
5 |
(0.6, 0.8, 0) |
(0, 0, -600) |
600 |
0 |
(0, 0, -1) |
(0, 0, 0) |
0 |
0 |
(0, 0, 0) |
Length is always non-negative. It does not tell you which way the vector
points. A velocity of (600, 0, 0) and one of (-600, 0, 0) both have length
600.
Normalize returns another vector. A successful result has length approximately
1, so it represents direction without the original magnitude:
Original vector = Direction * Magnitude
Direction = Normalize(Original vector)
Magnitude = Vector Length(Original vector)
These are pure calculations. They do not move an Actor, change the input vector, cache a result, or add an execution pin.
Units follow the input¶
The length nodes do not invent units. Their result uses the same base unit as the vector's components:
| Vector means | Components use | Length means |
|---|---|---|
Target Location - Start Location |
centimeters | distance in centimeters |
Get Velocity |
centimeters per second | speed in centimeters per second |
| normalized direction | no unit | approximately 1 |
| arbitrary RGB-style data | arbitrary values | mathematical magnitude, not world distance |
In normal Unreal world-scale projects, one Unreal unit is one centimeter. That
does not make every vector a location: velocity, direction, scale-like data,
and world position can all use the same Vector pin type.
Length or Length XY?¶
Choose based on the movement plane, not on which number looks better.
Get Velocity
-> Vector Length XY
-> GroundSpeed
This ignores jump and fall velocity. A Character falling straight down can have a large 3D speed while its ground speed remains zero. That is usually what a walking Blend Space needs.
Use full Vector Length when vertical motion belongs in the answer:
- flight and swimming;
- homing projectiles;
- free-flying cameras;
- distance between two arbitrary 3D points;
- impact or physics velocity magnitude.
Ignoring Z is a design choice, not a general performance trick. On steep slopes, XY speed is the horizontal projection rather than total speed along the slope.
See Get Velocity for where Actor velocity comes from and why direct transform changes can still report zero.
Normalize and the near-zero case¶
A zero vector cannot be divided by its length because that length is zero. Very tiny vectors are also poor directions: dividing by a tiny number can turn floating-point noise into a seemingly decisive unit vector.
Normalize therefore uses a safety check:
pseudocode - not engine source
if SquaredLength(A) is large enough for Tolerance:
return A / sqrt(SquaredLength(A))
else:
return (0, 0, 0)
The node's Tolerance is a minimum squared vector length, not an ordinary
distance. The default is appropriate for ordinary gameplay math. Change it
only when the scale and meaning of your data justify a different cutoff.
The fallback is silent. There is no None, failure Boolean, warning, or
exception. If zero direction means "no target direction" in your graph, test
for that state before acting:
ToTarget = TargetLocation - SourceLocation
if Vector Length Squared(ToTarget) > MinimumDistance * MinimumDistance:
Direction = Normalize(ToTarget)
use Direction
else:
treat source and target as being at the same point
Do not lower tolerance just to force an answer from two almost identical positions. Decide what "close enough" means for the gameplay system.
The patterns everyone actually uses¶
Distance from one point to another¶
Offset = TargetLocation - StartLocation
Distance = Vector Length(Offset)
The length of either world location by itself is its distance from world origin, which is rarely the intended question.
Direction and distance together¶
Offset = TargetLocation - StartLocation
Distance = Vector Length(Offset)
Direction = Normalize(Offset)
Keep both values when arrival logic needs distance while movement or aiming needs direction.
Ground speed for animation¶
OwnerCharacter
-> Get Velocity
-> Vector Length XY
-> set GroundSpeed
This is actual movement speed, not input intent. A blocked Character may have movement input while velocity remains near zero.
A displacement for this frame¶
FrameDisplacement = Direction * Speed * DeltaSeconds
Direction should be unit length, Speed is distance per second, and
DeltaSeconds converts that rate into a per-frame distance. Normalize does not
make manual movement frame-rate independent by itself; see
The frame.
Diagonals and movement input¶
Combining full-strength forward and right values produces (1, 1, 0), whose
length is about 1.414. A custom system that multiplies this vector directly
by speed can move diagonally about 41 percent faster.
For digital input, combine first and then limit the result:
Desired = Forward * ForwardAxis + Right * RightAxis
if Vector Length Squared(Desired) > 1:
Desired = Normalize(Desired)
Some movement systems already constrain accumulated input, but custom movement code should make its own magnitude rule explicit. See Add Movement Input for the Pawn and Character input path.
For an analog stick, unconditional normalization is usually wrong:
Stick = (AxisX, AxisY, 0)
Normalize(Stick) // turns a small tilt into almost full strength
Instead, preserve values inside the unit circle and clamp only values above
length 1. Apply a dead zone before movement if the device needs one. Tier 36's
Enhanced Input modifier page covers that input-specific path.
Is it okay to normalize every frame?¶
Yes, when a direction is genuinely changing each frame. These nodes are small, side-effect-free math operations. Correctness is usually more important than trying to avoid one square root.
Still, normalize at the point where the value becomes a direction:
- do not repeatedly normalize a known unit vector such as
Get Forward Vector; - do not normalize and then expect to recover the old speed;
- do not normalize each axis separately before combining them;
- do not normalize analog input when its magnitude is intentional;
- do normalize changing offsets, surface directions, or custom movement directions before code assumes unit length.
Squared length for comparisons¶
Vector Length Squared and its 2D/XY counterpart skip the square root. Use
them when the only question is whether one distance is above or below a
threshold:
Offset = TargetLocation - StartLocation
Vector Length Squared(Offset) <= AttackRange * AttackRange
Both sides must be squared. Comparing squared length directly with
AttackRange mixes different units and gives the wrong boundary. Do not show
squared length to a player as if it were a distance, and do not use it as a
speed value for animation.
The C++ twins¶
For the curious, the same operations in original example code are:
const FVector Velocity = ControlledActor->GetVelocity();
const double Speed3D = Velocity.Size();
const double GroundSpeed = Velocity.Size2D();
const FVector Offset = TargetLocation - ControlledActor->GetActorLocation();
const double DistanceSquared = Offset.SizeSquared();
if (DistanceSquared <= FMath::Square(AcceptanceRadius))
{
return;
}
const FVector Direction = Offset.GetSafeNormal();
Size, Size2D, SizeSquared, and GetSafeNormal are FVector operations.
Use the engine's safe-normal helper rather than dividing by length manually.
Lookalikes - which one do I want?¶
| Node | Returns | Use when | Watch out |
|---|---|---|---|
| Vector Length | Real | You need full 3D distance or speed. | Includes Z. |
| Vector Length XY | Real | You need horizontal/ground magnitude. | Discards vertical motion. |
| Vector Length Squared | Real | You only need a threshold comparison. | Compare with a squared threshold. |
| Normalize | Vector | You need direction without magnitude. | Near-zero input returns zero. |
| Get Forward Vector | Unit Vector | You need the X-forward direction of a rotation/component. | It is already a direction, not a location. |
| Get Unit Direction Vector | Unit Vector | You want the direction from one point to another. | Coincident points still produce zero. |
| Distance (Vector) | Real | You want distance between two points directly. | It is the length of their difference. |
| Clamp Vector Size | Vector | You need to limit magnitude without forcing small values to length 1. |
Choose 2D vs 3D deliberately. |
Going deeper¶
- Get Forward Vector & Find Look at Rotation - direction sources, world-space points, and aim rotations.
- Get Velocity - actor velocity, ground speed, and zero-velocity cases.
- Blend Spaces in Animation Blueprints - using ground speed as animation data.
- Lerp, FInterp To, and moving things smoothly - interpolation is not normalization.
- Official docs: Vector Length, Vector Length XY, and Normalize.
- Engine source (requires engine access - we do not reproduce it here):
Kismet wrappers such as
UKismetMathLibrary::VSize,UKismetMathLibrary::VSizeXY, andUKismetMathLibrary::Normalare declared inEngine/Source/Runtime/Engine/Classes/Kismet/KismetMathLibrary.hand implemented inEngine/Source/Runtime/Engine/Private/KismetMathLibrary.cpp; vector math such asTVector::Size,TVector::Size2D, andTVector::GetSafeNormallives inEngine/Source/Runtime/Core/Public/Math/Vector.h.