Vision Cones for Unity3D

Why I made this tool
For a game I worked on at Voodoo, I implemented some AI behaviours for the enemy characters to allow them to look for weapons in the environment and to engage in combat with other characters. As I was developing that, I realised how difficult debugging these behaviours would be without a visual representation of what the enemies were seeing.
I couldn’t find an asset to draw a field of view vision cone that looked or behaved the way I wanted for this use, so I decided to write my own implementation using only the resources that the engine provides, with no external dependencies.

Creating a Vision Cone
The simplest approach I came up with in order to draw these vision cones was to split the shape into simpler ones: the sides of the cone, and its base. It doesn’t matter if the vision cone is 2D or 3D , this logic remains similar.
For the sake of simplicity, let’s stick to the implementation of a 2D vision cone, assuming that it is h
tall and has a field of view of alpha
degrees. Let’s also assume the vision cone will be placed at the origin of coordinates and will face the forward direction.
For the sides of the cone, drawing two lines that go from the origin to the corners of the vision cone will sufice. Calculating the position of each corner is as simple as rotating a forward vector of h
length, which stars at the origin, by -0.5f*alpha
degrees and +0.5f*alpha
degrees respectively on the upwards direction.
A vision cone with a flat base (i.e. a triangle) can be completed by just drawing another line from corner to corner. However, for one with a curved base, a custom Gizmos
shape is needed.
A custom
Gizmos
shape can be created by using the Gizmos.DrawLineStrip method, which requires a list ofVector3
points.

In this case, the shape needed is a circunference section, of amplitude alpha
, from a circle centered at the origin with a radius of h
. How many points to use for the line strip is up to us. The more points, the more “smooth” the vision cone will look. What I did is set a density of two points per unit of length and then multiply the length of the circumference section by it. Finally, I also added a baseline of 3 points to still display a curve even when the radius is too small.
int circunferenceSectionPoints = BASELINE_POINTS + POINTS_PER_UNIT_OF_DISTANCE * Mathf.RoundToInt(h * alpha * Mathf.Deg2Rad);
float angleBetweenPoints = alpha / circunferenceSectionPoints;
Getting the positions of these points can be done by modifying the vector math used earlier to get the corners: For each point i
, rotate a forward vector of h
length, which starts at the origin, by -0.5f*alpha + i*angleBetweenPoints
git degrees on the upward direction. Add each point to a list, call the Gizmos
method discussed above, and the field of view vision cone should be ready.
Gizmos or Line Renderer
I originally intended to keep this implementation as an internal tool built using Gizmos
. However, during the development of the game, our team considered the possibility of displaying the vision cones to the player during gameplay. Gizmos
are editor tools, which means that they are not inlcuded by default in release builds of the game.
Since I already had the math figured out, I also wrote another implementation of the logic using a LineRenderer
instead of the engine’s Gizmos
system, which can be exported and used on release builds of the game just like any other asset.
I tried to keep the usage consistent between both implementations, so calling the methods below with the same parameters should produce two vision cones that look the same:
GizmosVisionCones.Draw3DVisionCone(float newFieldOfView, float newDepthCone, bool newIsFlat);
aLineRendererVisionConeInstance.SetVisionConeParameters(float newFieldOfView, float newDepth, bool newIsFlat)
Another advantage of the LineRenderer
implementation of this tool is that it allows for easier and further customization through exposed inspector parameters that are specific to the LineRenderer
component, which artists and designers can change without dealing with code.

Download the tool
Down below is a link to the project repository. A .unitypackage
asset can be found in the releases section, which includes the required scripts and a few samples to showcase its usage. Alternatively, the source code of the scripts can be copy-pasted to a Unity3D project without the samples.