How do I draw simple shapes?

I want to be able to draw both solid shapes and lines, much like how Flash has fills and strokes. My dilemma is that I have to decide whether to draw them on a canvas or not. I can draw a solid shape on a canvas using UnityEngine.UI.Graphic like this:

using UnityEngine;
using UnityEngine.UI;

[ExecuteInEditMode]
public class UpArrow : Graphic
{
	public float size;

	protected override void OnPopulateMesh ( VertexHelper vh )
	{
		if ( shouldDraw )
		{
			vh.Clear ();

			Vector2 [] vecs = {
				
				new Vector2 ( 0, halfSize ),
				new Vector2 ( -halfSize, 0 ),
				new Vector2 ( -quarterSize, 0 ),
				new Vector2 ( -quarterSize, -halfSize ),
				new Vector2 ( quarterSize, -halfSize ),
				new Vector2 ( quarterSize, 0 ),
				new Vector2 ( halfSize, 0 )
			};

			for ( int i = 0 ; i < vecs.Length ; i++ )
			{
				vh.AddVert ( vecs [ i ], color, Vector2.zero );
			}

			vh.AddTriangle ( 0, 1, 6 );
			vh.AddTriangle ( 2, 3, 4 );
			vh.AddTriangle ( 4, 5, 2 );
		}
	}

	protected override void Awake ()
	{
		base.Awake ();

		halfSize	= size / 2;
		quarterSize	= size / 4;
	}

	private bool shouldDraw = true;
	private float halfSize;
	private float quarterSize;

}

However, if I want to draw lines with UnityEngine.LineRenderer I can’t use a canvas. And any solid shapes I draw using a CanvasRenderer will automatically go on top of any lines.

LineRenderer seems appealing because it gives the option of rounded end caps, which can be used to draw a solid circle if you make a line with its two ends in the same position. Is there any way to get that kind of functionality on a canvas? Or is there any way to get the functionality of Graphic outside of a canvas?

Here’s a script that will create a polygon, in this example I’ve set it to a rough pentagon

using System.Collections.Generic;
using UnityEngine;

public class DrawShape : MonoBehaviour {

    void Start()
    {
        Vector2[] vertices = new Vector2[] { new Vector2(1, 1), new Vector2(.05f, 1.3f), new Vector2(1, 2), new Vector2(1.95f, 1.3f), new Vector2(1.58f, 0.2f), new Vector2(.4f, .2f) };
        ushort[] triangles = new ushort[] { 0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 5, 0, 5, 1 };
        DrawPolygon2D(vertices, triangles, Color.red);
    }

    void DrawPolygon2D(Vector2[] vertices, ushort[] triangles, Color color)
    {
        GameObject polygon = new GameObject(); //create a new game object
        SpriteRenderer sr = polygon.AddComponent<SpriteRenderer>(); // add a sprite renderer
        Texture2D texture = new Texture2D(1025, 1025); // create a texture larger than your maximum polygon size

        // create an array and fill the texture with your color
        List<Color> cols = new List<Color>(); 
        for (int i = 0; i < (texture.width * texture.height); i++)
           cols.Add(color);
        texture.SetPixels(cols.ToArray());
        texture.Apply();

        sr.color = color; //you can also add that color to the sprite renderer

        sr.sprite = Sprite.Create(texture, new Rect(0, 0, 1024, 1024), Vector2.zero, 1); //create a sprite with the texture we just created and colored in

        //convert coordinates to local space
        float lx = Mathf.Infinity, ly = Mathf.Infinity;
        foreach (Vector2 vi in vertices)
        {
            if (vi.x < lx)
                lx = vi.x;
            if (vi.y < ly)
                ly = vi.y;
        }
        Vector2[] localv = new Vector2[vertices.Length];
        for (int i = 0; i < vertices.Length; i++)
        {
            localv _= vertices *- new Vector2(lx, ly);*_

}

sr.sprite.OverrideGeometry(localv, triangles); // set the vertices and triangles

polygon.transform.position = (Vector2)transform.InverseTransformPoint(transform.position) + new Vector2(lx, ly); // return to world space
}
}
You can feed it whatever vertices you want and map the triangles, here’s a visualization
[102584-polygons.png|102584]_
_