- Home /
For an NPC, is it more efficient to use a Trigger or calculate distance from a point?
So, I'm making an NPC Interaction system and it needs to test whether the player is within range of the NPC. However, I want to know if it would be more efficient for me to simply put a large trigger around the NPC and use:
void OnTriggerEnter2D(Collider2D player) // when the player overlaps with the NPCs Collision Box
{
inRange = true; // Note the player is in range of the NPC
}
Or for me to use Pythagoras to constantly calculate distance. eg:
void Update()
{
float dist = Mathf.Sqrt(System.Math.Abs(transform.position.x - PlayerController.playerPos.x) + System.Math.Abs(transform.position.y - PlayerController.playerPos.y)); // Calculate Distance to player
if (dist < 5)
{
inRange = true;
}
Obviously, the second method may be intensive for more NPCs, so I'm wondering what to use.
Just a note: there is a Vector3.Distance method you can use ins$$anonymous$$d of calculating it by hand
I'm Working in 2D, but Thanks, didn't know Vector2.Distance was a thing =P Probably does the same thing that I'm doing anyway though, just shorthand.
Answer by JVene · Oct 15, 2018 at 12:13 PM
That's not Pythagoras. Drop Abs, it doesn't do anything for you. Square the subtractions of x and y. THEN it's Pythagoras.
That said, you can skip the Sqrt (which is the heaviest part of the calculation), and compare against the square of the range (25 in your example). That does the same thing, but faster.
Triggers are heavier. They are heavier because there's a callback, and because the trigger is calculated against the dimensions and nature of the colliders used as a trigger. In theory a circle or spherical collider is the same as a distance calculation, but it isn't inline. For that matter, using Distance isn't inline. If you do the calculation yourself, as you've attempted, it is inline. That avoids the overhead of a method call. The only thing a collider does to "help" is in the broadphase, where (probably) axis aligned bounding boxes are used to reject obvious non-collisions quickly.
You can do the same kind of thing with a minor optimization in 2D. After you perform the subtraction (and save that as your own X and Y), you can test to see if both X and Y have an Abs magnitude greater than your range. When either are greater, the distance can't be within the radius of your range. If, however, both are in range, then you perform the squares and test against range squared. That proves the range is within the circle inscribed in the implied square by the previous test (or isn't). You can do the sqrt if you really prefer, but the results aren't changed by doing that. For a range like you've described it's just extra work compared to the requirement (unless, of course, you need to otherwise use the actual range in other calculations or display).
Your answer
Follow this Question
Related Questions
Activate trigger if items colected 1 Answer
If gameObject's center passes through a trigger? 1 Answer
Play Animation OnTriggerEnter 2 Answers
Targeting the GameObject I collide with? 1 Answer
Whats wrong with my score script 1 Answer