- Home /
Regarding the efficiency of enemy detection
I've got a far bit from reading various questions & answers, but there's a few questions still going through my head. I hope it's alright to air them here.
So I'm trying to do a pretty standard Enemy detection script for an AI state. But as I'm new to Unity (and 3D) I'm unsure the most effcient way.
I'm thinking it should be something like:
Check whether the player is within range of the enemy
Check to see whether the enemy is rotated towards the player
Do a raycast to see whether they have line of sight.
My questions are: What's the most efficient way of checking range? Calculating the distance or checking interaction with a Trigger object? I'm currently assuming that a RayCast would be the most inefficient calculation out of the above steps, so left it until last, do people agree?
Thanks all.
Answer by Avaista · Jul 15, 2012 at 06:07 PM
As always, it is very dependent on your desired game behavior.
Trigger Colliders offer a great deal of flexibility most of the time, because you interact with them using OnTriggerEnter or OnTriggerExit, which means different enemies can have diffently shaped agro area(Boxes, Spheres, Capsules and even Mesh triggers(more on this soon)
RayCasts are not the most expensive thing in the world. What is important to remeber when doing any kind of Physics detection (raycasts, triggers) is the Physics Layer matrix (Edit->Project Settings->Physics).
If you cast a ray against only the player layer, for instance, you will only have a few things to detect against, which makes the calculation that much faster. Same concept applies with a trigger collider.
One thing that I have done in the past for automated turrets is give them a cone mesh collider turned into a trigger. If the turret is an Enemy Turret, the collider is placed on the "EnemyTargeting" layer(for this example). Which only interacts(set through the Physics Manager) with things on the "Player" layer. Now I can assume that ANYTHING that enters activates that OnTriggerEnter is something that I want to shoot. After that I send a raycast every .2 seconds towards the player to see if there is anything in the way. Now you can replace raycast with sphere cast or capsule cast or whatever, and you can set the layermask before you fire it, aka
int layerMask = 1 << LayerMask.NameToLayer("Obstacles");
By A) Reducing the number of items I'm checking for by setting a particular layer and B) Reducing the number of Rays Im sending by only shooting one every .2 seconds(rather than every frame [[5 times a second vs 60]]
I can create an efficient, flexible aggro detection for a turret. If the player leavs my trigger, I simply stop shooting Raycasts(you can do this several ways depending on how youve set it up(aka: Coroutines/invoke repeating etc)
Now a slight modification to this is to assume that the trigger is not your viewing area, but rather an area you(in this case your enemy) are defending. Since the trigger no longer represents your target area, you will need to add checks to make sure the target is in.
In the case of a cone, this can be a simple dot product against the enemy forward and the relative location of the player.
IF In trigger AND In cone of vision AND In sight(Raycast point above) THEN RageOfTheBrooklynVariety(target);
Semi-Not-Really-More-Like-Hemi Pro Tip:
Square Root Sucks. If you are doing your ranged detection
(Vec1-Vec2).sqrMagnitude < sqrRange
Is far faster than
(Vec1-Vec2).magnitude < range
Which is what Vector3.Distance is
because distance is x^2 + y^2 + z^2 = d^2
I would argue it matters in the long run. Practically no, it will probably not kill you, but it is a good habit to get into.
I work in XNA as well as Unity. One of my favorite stories was about a peer who was making a simple 2D game. He had lag, i mean like 2-3 frames a second lag. We found one place where he had been using the Pythagorean method, with sqare root. Against x enemies every frame. We changed it out and it jumped to 60 frames a second. To be fair, there were alot of enemies. But the effect was hilarious.
Thanks guys. Appreciate the full and quick responses. Like the idea of the targeting 'cone', solves a lot of problems all pretty neatly.
We use Pythagorean equations all the time (2D games too), good to know if things start grinding to a holt.