GDKB

Distance Calculation

Beginner20 Minutes readUpdated July 21, 20263 related concepts

The distance between two points is the magnitude of the vector you get by subtracting one position from the other — there is no separate "distance formula" to memorize beyond the vector operations already covered. Subtract to get the offset, take its magnitude to get the distance. This one combination answers an enormous share of common gameplay questions: is the enemy in range, which pickup is closest, has the player reached the destination.

On this page

Distance Calculation

Summary

The distance between two points is the magnitude of the vector you get by subtracting one position from the other — there is no separate "distance formula" to memorize beyond the vector operations already covered. Subtract to get the offset, take its magnitude to get the distance. This one combination answers an enormous share of common gameplay questions: is the enemy in range, which pickup is closest, has the player reached the destination.

Why This Matters

Nearly every gameplay system needs to answer "how far apart are these two things" at some point — attack range, detection radius, proximity triggers, sorting objects by closeness. Without recognizing that distance is just "subtract, then measure the result," it's easy to reach for ad-hoc, error-prone approaches (comparing X and Z separately, for instance) that don't generalize correctly to diagonal or 3D relationships. Understanding distance as a direct consequence of vector subtraction and magnitude means one mental model covers every one of these situations.

Mental Model

Distance is the length of the string stretched taut between two pins, not a separate measurement you take some other way. Push two pins into a board and stretch a piece of string directly between them — the string's length, once pulled straight, is the distance, regardless of which direction the pins happen to be from each other. That "stretch a string between them and measure it" is exactly what subtracting one position from another and taking the result's magnitude computes.

Core Explanation

  • Distance is magnitude(pointB - pointA). Subtracting the two positions produces the offset vector pointing from one to the other; taking that offset's magnitude gives a single non-negative number: the distance.
  • The Pythagorean theorem underlies distance in any number of dimensions. In 2D, this is the familiar right-triangle formula; in 3D, the same idea extends by adding a third squared term before the square root — this is exactly the magnitude calculation from [[CON-0044]].
  • Distance is symmetric. distance(A, B) and distance(B, A) are always equal — direction doesn't matter for a plain distance value, only for the offset vector it was derived from.
  • Squared distance avoids an unnecessary square root for pure comparisons. Exactly as with magnitude, comparing two squared distances gives the same ordering as comparing the real distances, at a fraction of the computational cost.

Syntax / Theory

Engine-neutral (formula)

text
distance(A, B) = magnitude(B - A)

2D: distance = sqrt((Bx-Ax)^2 + (By-Ay)^2)
3D: distance = sqrt((Bx-Ax)^2 + (By-Ay)^2 + (Bz-Az)^2)

C# (Unity)

csharp
float distance = Vector3.Distance(pointA, pointB); // Equivalent to (pointB - pointA).magnitude.
float sqrDistance = (pointB - pointA).sqrMagnitude; // Cheaper, for comparisons only.

C++ (Unreal)

cpp
float Distance = FVector::Dist(PointA, PointB);
float SqrDistance = FVector::DistSquared(PointA, PointB);

Both engines provide a dedicated distance helper (Vector3.Distance, FVector::Dist) as a convenience — internally, both are computing exactly "subtract, then take the magnitude," matching the manual formula above.

Practical Example

A "closest pickup" search compares squared distances to avoid unnecessary square root calculations across many candidates.

csharp
Transform FindClosestPickup(Vector3 playerPosition, List<Transform> pickups)
{
    Transform closest = null;
    float closestSqrDistance = float.MaxValue;

    foreach (var pickup in pickups)
    {
        float sqrDistance = (pickup.position - playerPosition).sqrMagnitude;
        if (sqrDistance < closestSqrDistance)
        {
            closestSqrDistance = sqrDistance;
            closest = pickup;
        }
    }
    return closest;
}

Every candidate is compared using squared distance — the actual distance value is never needed, only which candidate is smallest, so the square root is skipped entirely for every pickup checked.

Common Mistakes

  • Computing full (square-rooted) distance inside a loop that only needs comparisons. Calling Vector3.Distance repeatedly to find the smallest of many candidates does unnecessary work — squared distance comparison gives the identical result faster.
  • Comparing raw distances to a squared threshold, or vice versa. Mixing squared and non-squared values in the same comparison (e.g. sqrDistance < range instead of sqrDistance < range * range) produces an incorrect result.
  • Ignoring the Y axis unintentionally in a 3D game when a 2D "ground distance" was actually needed, or vice versa — measuring true 3D distance when a flying enemy's height difference shouldn't count toward an attack range check on the ground.
  • Recomputing the same distance multiple times per frame instead of calculating it once and reusing the value — a common inefficiency when several separate checks (range, line-of-sight priority, UI display) all independently need the same distance.

Game Development Example

An enemy's detection logic uses squared distance for the cheap "is anything nearby at all" check, then falls back to true distance only for targets that pass that first filter and need finer-grained falloff logic.

csharp
public class EnemyDetection : MonoBehaviour
{
    public float detectionRadius = 15f;

    void Update()
    {
        float sqrDist = (player.position - transform.position).sqrMagnitude;
        if (sqrDist <= detectionRadius * detectionRadius) // Cheap first-pass filter.
        {
            float actualDistance = Mathf.Sqrt(sqrDist); // Only computed for real candidates.
            AdjustAlertnessBasedOnDistance(actualDistance);
        }
    }
}

Reusing sqrDist to derive actualDistance (via Mathf.Sqrt) instead of calling Vector3.Distance separately avoids redoing the subtraction and squaring work that was already done for the first check.

Best Practices

  • Default to squared distance for filtering/comparison; compute true distance only when the actual numeric value is needed downstream.
  • Reuse an already-computed distance or squared-distance value rather than recalculating it for multiple checks in the same frame.
  • Be explicit about whether a distance check should include all axes (true 3D distance) or intentionally ignore one (e.g. height, for a ground-based range check).
  • Square comparison thresholds consistently whenever comparing against squared distance.

Exercises

  1. Compute the distance between (0, 0, 0) and (3, 0, 4) by hand, then verify it matches the engine's Vector3.Distance result.
  2. Take the FindClosestPickup example and modify it to ignore the Y axis entirely (treat it as a flat, top-down distance check) — explain when this variant would be more appropriate than full 3D distance.
  3. You're building a large-scale RTS with hundreds of units checking distances to each other every frame for AI decisions. Decide how aggressively to rely on squared distance versus true distance throughout this system, and justify the trade-off in terms of overall performance.
  4. Research spatial partitioning structures (like a grid or quadtree) and explain, in your own words, why checking distance to every other object individually becomes a performance problem as the object count grows, even with squared-distance optimization.
  • Vector Magnitude — distance is defined directly as the magnitude of a subtracted offset vector; understanding magnitude is a direct prerequisite.
  • Vectors — vector subtraction is the first step of every distance calculation, making basic vector arithmetic a necessary foundation.
  • Direction Vectors — the same subtraction used to find distance also produces the offset vector that, once normalized, gives the direction between the two points.

Further Reading

Related Concepts