You can not draw anything from Update since Update runs before the rendering even starts. Debug.DrawLine also does not draw any lines, it just queues the line information to be drawn during rendering. You can do something similar yourself with a singleton monobehaviour using OnRenderObject to draw all the queued lines. There’s no way around that. When the rendering actually starts, the first actions is usually to clear the screen. So even when you could render something directly in Update, it would be erased when the actual scene renders. You can directly draw to the screen from inside OnGUI when the event type is “Repaint”. This is usually a good point to draw such lines since that happens after the normal scene rendering.
What approach might be the best depends on what you actually need this for. If you really just want to draw / redraw the line(s) every frame you could just use the GL class to draw all the queued lines on the fly. If you want to draw them permanentally or for a larger period of time, creating a Mesh with topology “lines” might be a better approach. In any case you would use a list of queue to accumulate all the line information during the update cycle in order to draw them during [the rendering phase]. As I said you have to use either OnRenderObject, OnRenderImage, OnGUI or a coroutine that waits for WaitForEndOfFrame.
My old [simulation to show how FixedUpdate works] is entirely created in OnGUI. All lines are drawn using the GL class.
I quickly created a simple example script:
public class Lines : MonoBehaviour
public class Line
public Vector3 startPos;
public Vector3 endPos;
public Color color;
public float timeout;
private static Lines m_Instance = null;
private static Lines GetInstance()
if (m_Instance == null)
m_Instance = new GameObject("Lines").AddComponent<Lines>();
m_Instance.hideFlags = HideFlags.DontSave;
private List<Line> m_Lines = new List<Line>();
public Material lineMaterial;
private void Awake()
lineMaterial = new Material(Shader.Find("Legacy Shaders/Particles/Alpha Blended"));
private void OnRenderObject()
var cam = Camera.current;
var matrix = cam.projectionMatrix * cam.worldToCameraMatrix;
GL.modelview = Matrix4x4.identity;
float currentTime = Time.time;
for(int i = m_Lines.Count - 1; i >= 0; i--)
var line = m_Lines*;*
if (currentTime > line.timeout)
public static void Add(Vector3 aStart, Vector3 aEnd, Color aColor, float aDuration = 0)
var line = new Line
startPos = aStart,
endPos = aEnd,
color = aColor,
timeout = 0
if (aDuration > 0)
line.timeout = Time.time + aDuration;
This is a singleton class that will instantiate itself. It creates a material with the legacy alpha blended particle shader since that shader is one of the few that actually uses vertex colors. You can use
Lines.Add(start, end, color); from anywhere to queue a single line for rendering. This line will be drawn only once and will be removed the next frame. You can also add a duration value which will keep the line for the specified in-game time.
Here’s a simple example usage:
public class TestScript : MonoBehaviour
var p = transform.position;
float radius = 10f;
Lines.Add(p+Random.insideUnitSphere * radius, p+Random.insideUnitSphere * radius, new Color(1,0,0,0.5f), 5);
This will create a new random line every frame within a 10 unit radius around the gameobject this script is attached to. Each line will last for 5 seconds. At a framerate of 60 fps this would result in about 300 active lines after 5 seconds.
Since we use OnRenderObject and since we use Camera.current we will also see those lines in the scene view. If you use a different drawing method (for example OnGUI) you may only see them in the game view.
: Unity - Manual: Order of execution for event functions
: Unity WebGL Player | HowUnityWorks