Draw lines in Unity

To draw lines in Unity we are all fine with LineRenderer, but sometimes we just need a simple straight line to be rendered on the screen. Actually most graphic hardware draws filled triangles, and the rest of the visuals builds up from these fundamental pieces. Another option is to draw stroked triangles, or stroked line pairs. This feature allows us to draw a single line, and is available in Unity using static UnityEngine.GL methods (similar to OpenGL Immediate Mode).

TL;DR

I made some classes for everyday use suitable to draw Immediate Mode lines with colors, go grab EPPZ.Lines at GitHub. Along the example scenes they are all self-explainatory.

Use EPPZ.Lines at

DrawCalls in a nutshell

A frame on the screen can be considered as a three-phase process. First the application running on the CPU (Central Processing Unit) collects / organizes data to be submitted to the graphics card, to the GPU (Graphics Processing Unit). Second, the actual data submission towards the graphics hardware, some terminology call this phase “upload”. Finally the graphics card executes the commands using the uploaded data.

Basically the second, upload phase can be considered as a DrawCall. The golden performance rule here is that data uploading is expensive / time consuming operation, and executing the commands are not. So packing up all the data into batches, and uploading them in a few DrawCall saves performance a lot. Having this, caching, buffering all the vertex / texture data has evolved over the time. Even static (can say beforehand), or dynamic (can say on-air, or during runtime).

Draw lines in Unity using Immediate Mode

Immediate Mode drawing originates from the early days of computer graphics, and on its own is really not performant. It constructs a pack of data, and submits the pack in a distinct DrawCall every time, every frame. Using static UnityEngine.GL methods in Unity, drawing a single line looks like this one below.

GL.Begin(GL.LINES);
GL.Color(color);
GL.Vertex(from);
GL.Vertex(to);
GL.End();

However, within a UnityEngine based runtime, you cannot execute these methods on their own, you have to call it from a UnityEngine.Camera callback called OnPostRender(). A full MonoBehaviour script ready to be attached to a Camera looks like the following.

public class LineRenderer : MonoBehaviour
{
    void OnPostRender()
    {
        GL.PushMatrix();
        GL.LoadProjectionMatrix(GetComponent().projectionMatrix);
        GL.Begin(GL.LINES);
        GL.Color(color);
        GL.Vertex(from);
        GL.Vertex(to);
        GL.End();
        GL.PopMatrix();
    }
}

If you need to draw only a couple of lines, or simply performance is not an issue, you are done with this article, go on and use the snippet above.

On the other hand, if you need to maintain multiple drawings in a single scene, you’ll probably want to take some kind of optimization into account.

Draw lines in Unity using EPPZ.Lines

While I made these classes for personal use to debug some production code, you may find it useful in the everydays of line drawing. EPPZ.Lines is just simply wraps up the boilerplate that surrounds Immediate Mode drawing.

You can drop a LineRendererCamera script to the camera you use for rendering, then after you created you own DirectLineRenderer subclasses, you can drop them to any object in the scene. The camera script automatically collects any line renderer you made upon Awake().

Your scripts will really be free of any boilerplate code, only the features you are about to implement, and they can reside anywhere in the scene, unbound from the rendering camera object.

public class LineRenderer : EPPZ.Lines.DirectLineRenderer
{
    protected override void OnDraw()
    {
        DrawLine(from, to, color);
    }
}

These classes come with some further helper methods to draw circles and rectangles using DrawCircle() and DrawRect(). Also contains a shortcut to draw point array polygons using DrawPoints().

public class DrawingRenderer : EPPZ.Lines.DirectLineRenderer
{
    protected override void OnDraw()
    {
        DrawPoints(points, color);
        DrawRect(bounds, color);
        DrawCircle(center, radius, 64, color); // Circle with 64 segments
    }
}

EPPZ.Lines classes mostly proven to be really a convenient debug tool, as they render :Debug.DrawLine: instances in the Scene View during runtime. Having this, you can nicely inspect the lines while navigating in Scene View space.

DISCLAIMER. THE INFORMATION ON THIS BLOG (INCLUDING BUT NOT LIMITED TO ARTICLES, IMAGES, CODE SNIPPETS, SOURCE CODES, EXAMPLE PROJECTS, ETC.) IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE INFORMATION ON THIS BLOG (INCLUDING BUT NOT LIMITED TO ARTICLES, IMAGES, CODE SNIPPETS, SOURCE CODES, EXAMPLE PROJECTS, ETC.).