Sam Afshari's Notes
  • GitHub
  • Twitter/X
  • All posts
  • Ed
  • NuGets
  • POIWorld
  • RedCorners

Lines in Unity - Fri, Feb 22, 2019

TL;DR: Download NeatLine from https://github.com/samafshari/NeatLine!

It is sometimes amazing how you want to do a very simple task, but you cannot find a simple and to-the-point library that does it for you. A few of my games require basic 2D lines, and Unity itself does not have the functionality to create 2D lines. There are a few complex assets on the Asset Store, but their licensing is not quite obvious, and I hesitate to open source my projects when using those assets.

Therefore I went ahead and created a simple dependencyless component that does one thing: Drawing 2D lines.

You can get it from GitHub using the link above. The main component is called NeatLine, which can be added to your Scene by clicking on the GameObject>2D Object>NeatLine menu item.

You can control four things about your line:

  • Vector2 HeadLocalPosition: Position of the first point, relative to the local transform.
  • Vector2 TailLocalPosition: Position of the second point, relative to the local transform.
  • float Thickness: Line’s thickness.
  • Color Color: Line’s color.

All four properties can be modified at edit or runtime.

Here’s how it works

To draw a custom shape in Unity, we need three things: MeshRenderer, MeshFilter and Material.

meshFilter = gameObject.AddComponent();
meshRenderer = gameObject.AddComponent();
material = Resources.Load("NeatLineMaterial");

But before drawing a shape, we need to create the shape (Mesh) itself, i.e. calculating vertices, triangles and indices.

Calculating vertices is easy. We need to get the normal vector, add thickness to it and get the four corners of the line:

Vector3[] GetPolygon()
{
    var vec = TailLocalPosition - HeadLocalPosition;
    var unit = vec.normalized;
    var halfCross = new Vector3(unit.y, -unit.x, 0) * 0.5f * Thickness;

    return new[]
    {
        new Vector3(HeadLocalPosition.x, HeadLocalPosition.y) - halfCross,
        new Vector3(HeadLocalPosition.x, HeadLocalPosition.y) + halfCross,
        new Vector3(TailLocalPosition.x, TailLocalPosition.y) + halfCross,
        new Vector3(TailLocalPosition.x, TailLocalPosition.y) - halfCross
    };
}

Based on these four vertices, the indices of our line are:

new[] { 0, 1, 2, 2, 3, 0 };

And these are enough for us to create the Mesh:

var mesh = new Mesh();
meshFilter.mesh = mesh;
mesh.vertices = GetPolygon();
mesh.triangles = new[] { 0, 1, 2, 2, 3, 0 };
mesh.RecalculateNormals();
mesh.RecalculateBounds();

The last step is to assign the color to the Material:

material.color = Color;

Alternatively, you can assign individual colors to each vertex:

mesh.colors = new[] { Color, Color, Color, Color };

And there we go. We have a line!

NeatPolyline

If you are seeking some more advanced features, such as multiple vertices per line, or individual color and thickness settings per vertex, you can use NeatPolyline.

For more information, please check out the GitHub page of the project.

Back to Home


© Sam Afshari 2024