# Different Ways to Find Distance

I’ve been learning Unity scripting lately, and I’ve been looking for ways to find the distance, and came upon two different ones.

The Unity manual/documentation (here: http://docs.unity3d.com/Manual/DirectionDistanceFromOneObjectToAnother.html) has a few different statements you can use to calculate the distance, but the “Unity Scripting API” (here: Unity - Scripting API: Vector3.Distance) uses a function build into Unity (Vector3.Distance) to find the distance.

Which way should people use, and which manual should I be reading from, out of these two?

Just wondering. Thanks…

As always, use the one that suits you best.

This example:

http://docs.unity3d.com/Manual/DirectionDistanceFromOneObjectToAnother.html

is using the Vector3 class when it does “heading.magnitude.” “Heading” is a Vector3. So in the manual it’s teaching generally how to do something while the scripting API is showing specifically what all the methods and so on do. I refer to both. Like toreau said, just use whatever suits you best.

If what you’re looking to do is find distance, I avoid using the Vector3 class methods because they’re relatively slow, probably due to the function call that’s done when internally the math is very simple. For instance this:

``````// Gets a vector that points from the player's position to the target's.
Vector3 heading = target.position - player.position;
``````

is many times slower than doing this:

``````Vector3 heading;
heading.x = target.position.x - player.position.x;
heading.y = target.position.y - player.position.y;
heading.z = target.position.z - player.position.z;
``````

There are no method calls here at all. I haven’t tested “magnitude” but suspect it’s similar. Square roots are very fast these days, not the big deal they used to be.

What I do now is prototype code using the Vector3 classes for dot, cross, distance, distance squared, and so forth, then when the algorithm is working I go back in and hand code all of it to eliminate the Vector3 method calls. I got my boat simulation physics to run about 10 times faster by doing that, some parts of it were up to 80 times faster. It really makes a difference.

Whether or not it’s worth the trouble depends what you’re doing though. If you’re only doing a distance calculation every now and then, it’s not worth bothering with, but if you’re doing thousands per second it starts to add up.

You got me curious so I decided to profile it in Unity 5. Here’s the test script:

``````using UnityEngine;
using System.Collections;

public class Test : MonoBehaviour {

private Vector3 firstPosition;
private Vector3 secondPosition;

// Use this for initialization
void Start()
{
firstPosition = new Vector3(1, 1, 1);
secondPosition = new Vector3(2, 2, 2);

}

void Test1()
{
for (int i = 0; i < 10000; i++)
{
Vector3 heading = firstPosition - secondPosition;
float distance = heading.magnitude;
}
}

void Test2()
{
for (int i = 0; i < 10000; i++)
{
float distance = Vector3.Distance(firstPosition, transform.position);
}
}

void Test3()
{

Vector3 heading;
float distance;
Vector3 direction;
float distanceSquared;

for (int i = 0; i < 10000; i++)
{
heading.x = firstPosition.x - secondPosition.x;
heading.y = firstPosition.y - secondPosition.y;
heading.z = firstPosition.z - secondPosition.z;

distanceSquared = heading.x * heading.x + heading.y * heading.y + heading.z * heading.z;
distance = Mathf.Sqrt(distanceSquared);

direction.x = heading.x / distance;
direction.y = heading.y / distance;
direction.z = heading.z / distance;
}
}

// Update is called once per frame
void Update()
{
Test1();
Test2();
Test3();
}
}
``````

Test1() uses the approach here: http://docs.unity3d.com/Manual/DirectionDistanceFromOneObjectToAnother.html

I stop short of computing the direction and just do distance there.

Test2() uses the Vector3.Distance() method from here: Unity - Scripting API: Vector3.Distance

Test3() does what I was suggesting by eliminating all of the Vector3 method calls. Here are the times:

Test1() 2.91 ms
Test2() 4.68 ms (or 7.11ms with 2 transforms)
Test3() 0.93 ms

With this test, Vector3.Distance as used in Test2() was slowest, probably because it’s accessing a transform in the middle of it along with the method calls. If you do two transforms in there which is probably more like your typical case (instead of one transform and one vector), it slows down more to 7.11 ms. So while it’s easy to use and you can do the distance computation in one line of code, it’s relatively slow because of at least two internal method calls including a pair of Transform.get_position() calls. I’d use it for prototyping, but probably not in actual code unless it was not being used very often.

Test1() is faster in this test just because I was using two vectors. In the more typical case you’d probably use transform.positions in there. I tested that and it slows it to 7.79ms which is even slower than Test2() with the Vector3.Distance method call.

Contrast the 7 to 8 ms call with Test3() which is the hand coded version with a single Mathf.Sqrt() call without any transforms in it and you’re almost 10 times faster. If you plop in transform.position in place of firstPosition and secondPosition, it ends up being twice as slow as the other two because you’re doing Transform() over and over again. In that case you’re better off just using the Vector3.Distance() function and being done with it.

Performance comes down largely to caching the variables and being clever with how you do the computations in the end. If you’re doing large numbers of distance computations on lots of objects, it may be best to stuff the data into a couple of big arrays and loop over them all in one shot in a single method call. These kinds of tricks got me at least 10 times faster physics code in the end. The profiler in Unity Pro is very good, there’s a lot to be gained with it.

5 Likes

Just adding that, most of the time, you can skip the sqrt entirely. Sqrt is an expensive operation. If you want to compare two distances to see which is closer, it’s the same to compare two distanceSquared values. If you want your NavMeshAgent to stop when it’s 2 units from its destination, stop when distanceSquared is 4.

1 Like

You have to realize that vectors are based on trigonometry. And the distance equations are pretty much based on trigonometry. It’s kind of 6 of one and half a dozen of the other. I mean, you could trace all the way back through the math and see which requires the largest number of math operations, but to do it right you need to find out how many CPU cycles each operation takes to see which is truly the most expensive. Doing a head to head comparison, like Todd Wasson did, is probably the best way to find out which is faster. But under the hood you’re doing basically the same thing either way.

Here is the raw distance formula. That’s the method that’s going to make the most sense to most people who don’t understand vectors. But the vector math is doing basically the same thing. You’re subtracting one point from the other like this video demonstrates. But then you still have to find the magnitude of the result vector in order to know the distance between the two. As this shows, calculating the magnitude of a vector still uses the Pythagorean theorem (in this case the 3D Pythagorean theorem).

So basically, its two different ways of doing the exact same thing. The magnitude equation for vectors uses the distance formula to find the magnitude of a vector. Notice that in the distance formula example, the first thing you did was subtract the two points and get them related to the origin at 0,0,0. That’s basically the same thing as subtracting two vectors. Then you used the 2D or 3D Pythagorean theorem, as appropriate, to calculate the actual distance between the two points. That’s exactly what the magnitude equation does.

Six of one. Half a dozen of the other. You can probably find other ways to calculate distance too. But it’s basically all about dealing with the length of a line that is not aligned with the axis which will involve some sort of angular calculation and subtraction.

Good posts, guys.

I guess it comes down to execution speed versus ease of use. For speed what I try to do is pay close attention to what’s being accessed. For instance, if you use transform.position somewhere or access another property, it’s going to slow things down just because it’s doing a function call somewhere rather than just reading a variable straight out of memory. That’s extra CPU cycles and memory reads. Sometimes there’s no way around it though, you have to get the positions if you want to compute distances.

The easiest way to do it is probably to just use Vector3.Distance. The ease comes at a price, but if you’re only doing it a few times per frame it’s not worth worrying about. My boat sim does thousands and thousands of forces, cross and dot products in the computation of those forces, etc., so speed is really critical. I even go to the trouble of computing the torque vectors myself to replace a lot of the work rigidbody.AddForceAtPosition (or whatever it’s called) has to do. When computing the forces, I add them into a big array of forces and positions, then cycle through them all in one function call, accumulating the total force and total torque in a float variable in a loop. In there the torque is computed from the position, etc…

At the end of the loop I do a single AddForce and a single AddTorque call. Presto, thousands of rigidBody.AddForceAtPosition calls have been eliminated and replaced with just two calls. It makes the code a lot bigger, but it’s much faster. Granted, if someone isn’t sharp on their 3D math it’s probably not something to chase, and if you’re not doing a lot of dots/crosses/forces then it’s not worth the trouble anyway.

Square root is really fast nowadays, I wouldn’t worry so much about it. It’s cheaper not to do it of course, but having said that, it’s not much more expensive than a couple of additions probably on today’s CPU’s. Square root is even faster than taking the absolute value of a number, believe it or not. In parts of my code where I do lots of absolute values, I actually replace those with square roots and a few multiplications because all that combined is still faster than Mathf.Abs()… Seems crazy, but that’s what the profile showed.

For comparing distances of course it’s better to just use the squared distance. No matter how fast square root is, NOT computing it is still going to be faster!

Benchmarks are generally both interesting and intriguing, but wouldn’t it be really interesting if these three methods created the same result?

I stripped down your code to just care about calculating the distance between the two Vector3s, and the results doesn’t match;

``````using UnityEngine;

public class Test : MonoBehaviour
{
Vector3 firstPosition = new Vector3( 1, 1, 1 );
Vector3 secondPosition = new Vector3( 2, 2, 2 );

void Start ()
{
Debug.Log ( "Test nr. 1 = " + Test1 () );
Debug.Log ( "Test nr. 2 = " + Test2 () );
Debug.Log ( "Test nr. 3 = " + Test3 () );
}

float Test1 ()
{
Vector3 heading = firstPosition - secondPosition;
return heading.magnitude;
}

float Test2 ()
{
return Vector3.Distance( firstPosition, transform.position );
}

float Test3 ()
{

Vector3 heading;
float distanceSquared;
float distance;

heading.x = firstPosition.x - secondPosition.x;
heading.y = firstPosition.y - secondPosition.y;
heading.z = firstPosition.z - secondPosition.z;

distanceSquared = heading.x * heading.x + heading.y * heading.y + heading.z * heading.z;
distance = Mathf.Sqrt(distanceSquared);

return distance;
}
}
``````

This results in the following values:

``````Test nr. 1 = 1.732051
Test nr. 2 = 11.04536
Test nr. 3 = 1.732051
``````

Am I missing/misunderstanding something?

EDIT: My bad, of course. I forgot to replace transform.position with secondPosition on line #23. I left my error for future reference.

Wow, I didn’t realize I’d be starting such a controversial thread.

Thanks for all the answers and posts… I have a much better grip on the vector-math stuff now because of this.

Yep, “square root is expensive” hasn’t been true for years. In fact a decent chunk of the time it takes to do System.Math.Sqrt (or Mathf.Sqrt) is actually the function call overhead. Along those lines, division is also not slow anymore, so going through contortions to avoid it is quite inadvisable. On my CPU, + - / * all take the same number of clock cycles.

–Eric

1 Like

I guess I should’ve just said, if you don’t need to do something, don’t do it. It’s faster to do nothing than to do something, no matter how fast it is. That was my only point.

Wow. I think I am little late haha. But I wanna ask a small question about this.
I have a script on my game. It’s working nicely, but I always think I can make it run smootherly.
When I click an object in the game, I want to make a Lerp of its position, and the mousePosition related to world space.
But I dont want that happens forever, so I want it to happen only when the distance between the object’s position and its goal position is greater than 10. (I know, seems weird, but it’s exactly what I want)
Then, my question: how can I do that with the smallest processing price? Rather check in a if using Vector3.Distance(), or the way @Todd-Wasson described in Test(3)?

Here’s what I already have:

``````void Update ()
{

if (beingClicked) {

goalPos = cam.ScreenToWorldPoint (Input.mousePosition);

}

//

if (Vector3.Distance (position, goalPos) > 10f) {

moving = true;

position = Vector3.LerpUnclamped (position, goalPos, Time.deltaTime * 10);
position.z = 0;

transform.position = position;

} else {

moving = false;

}

//

}
``````

I almost forgot to say: it’s a 2D game, but I’m using Vector3 cause I think it’s better to do that than to convert to Vector2, but I dont know, I may be wrong. Please tell me if I am.

Any help is welcome! Thanks in advance!

Lucas