Draw grid lines in game view?

What is the best way to show grid lines in game view… I want to show grid to the user in my game… I was wondering what is the most convenient way?

Since I have mouse selection on many objects, I do not want that the grid cause any problem with the selection…

2017-06-17 EDIT: Guys, this is now wayyyyy out of date. Many people report it not working anymore. Try to look through the later dated answers for any possible fixes, otherwise I know this code no longer works as is. Its your turn to develop a better one :wink:

This will probably be a bit overkill to what you want, but I’m too lazy to edit it.

alt textalt text

What you have here is code for a 3 dimensional double grid with editable total size, start position and grid step size. If you leave the Y size at 0, you will have a 2D grid. Additionally, numpad +/- lets you move it up and down. Attach this script to your camera.

(It also takes a plane object, because I needed collision for it, but you can comment out the 3 lines to do with the plane altogether with no loss of functionality).

using UnityEngine;
using System.Collections;

public class gridOverlay : MonoBehaviour {
	
	public GameObject plane;
	
	public bool showMain = true;
	public bool showSub = false;
	
	public int gridSizeX;
	public int gridSizeY;
	public int gridSizeZ;
	
	public float smallStep;
	public float largeStep;
	
	public float startX;
	public float startY;
	public float startZ;
	
	private float offsetY = 0;
	private float scrollRate = 0.1f;
	private float lastScroll = 0f;
	
	private Material lineMaterial;
	
	private Color mainColor = new Color(0f,1f,0f,1f);
	private Color subColor = new Color(0f,0.5f,0f,1f);
	
	void Start () 
	{

	}
	
	void Update () 
	{
		if(lastScroll + scrollRate < Time.time)
		{
			if(Input.GetKey(KeyCode.KeypadPlus)) 
			{
				plane.transform.position = new Vector3(plane.transform.position.x, plane.transform.position.y + smallStep, plane.transform.position.z);
				offsetY += smallStep;
				lastScroll = Time.time;
			}
			if(Input.GetKey(KeyCode.KeypadMinus))
			{
				plane.transform.position = new Vector3(plane.transform.position.x, plane.transform.position.y - smallStep, plane.transform.position.z);
				offsetY -= smallStep;
				lastScroll = Time.time;
			}
		}
	}
	
	void CreateLineMaterial() 
	{

	    if( !lineMaterial ) {
	        lineMaterial = new Material( "Shader \"Lines/Colored Blended\" {" +
	            "SubShader { Pass { " +
	            "    Blend SrcAlpha OneMinusSrcAlpha " +
	            "    ZWrite Off Cull Off Fog { Mode Off } " +
	            "    BindChannels {" +
	            "      Bind \"vertex\", vertex Bind \"color\", color }" +
	            "} } }" );
	        lineMaterial.hideFlags = HideFlags.HideAndDontSave;
	        lineMaterial.shader.hideFlags = HideFlags.HideAndDontSave;}
	}
	
	void OnPostRender() 
	{		
	    CreateLineMaterial();
	    // set the current material
	    lineMaterial.SetPass( 0 );
		
	    GL.Begin( GL.LINES );
		
		if(showSub)
		{
		    GL.Color(subColor);
			
			//Layers
			for(float j = 0; j <= gridSizeY; j += smallStep)
			{
				//X axis lines
				for(float i = 0; i <= gridSizeZ; i += smallStep)
				{
				    GL.Vertex3( startX, j + offsetY, startZ + i);
				    GL.Vertex3( gridSizeX, j + offsetY, startZ + i);
				}
				
				//Z axis lines
				for(float i = 0; i <= gridSizeX; i += smallStep)
				{
				    GL.Vertex3( startX + i, j + offsetY, startZ);
				    GL.Vertex3( startX + i, j + offsetY, gridSizeZ);
				}
			}
			
			//Y axis lines
			for(float i = 0; i <= gridSizeZ; i += smallStep)
			{
				for(float k = 0; k <= gridSizeX; k += smallStep)
				{
					GL.Vertex3( startX + k, startY + offsetY, startZ + i);
			    	GL.Vertex3( startX + k, gridSizeY + offsetY, startZ + i);
				}
			}
		}
		
		if(showMain)
		{
			GL.Color(mainColor);
			
			//Layers
			for(float j = 0; j <= gridSizeY; j += largeStep)
			{
				//X axis lines
				for(float i = 0; i <= gridSizeZ; i += largeStep)
				{
				    GL.Vertex3( startX, j + offsetY, startZ + i);
				    GL.Vertex3( gridSizeX, j + offsetY, startZ + i);
				}
				
				//Z axis lines
				for(float i = 0; i <= gridSizeX; i += largeStep)
				{
				    GL.Vertex3( startX + i, j + offsetY, startZ);
				    GL.Vertex3( startX + i, j + offsetY, gridSizeZ);
				}
			}
			
			//Y axis lines
			for(float i = 0; i <= gridSizeZ; i += largeStep)
			{
				for(float k = 0; k <= gridSizeX; k += largeStep)
				{
					GL.Vertex3( startX + k, startY + offsetY, startZ + i);
			    	GL.Vertex3( startX + k, gridSizeY + offsetY, startZ + i);
				}
			}
		}


	    GL.End();
	}
}

As I can’t edit posts yet, I figured I’d post an update to @Em3rgency’s answer, I’m not entirely sure what correct forum decorum here is, so if this should be a comment to @Em3rgency’s answer, then let me know and I’ll do that.

This code works in Unity5 by incorporating @dpolyakov’s answer and additionally fixes a bug that draw’s the mesh incorrectly when setting StartX/Y/Z. I’ve also removed the grid moving functionality, as I couldn’t see many use cases for that.

Same as before, put this in a C# script of it’s own, and then ensure it gets attached to a Camera object.

using UnityEngine;
using System.Collections;

public class GridOverlay : MonoBehaviour
{

    //public GameObject plane;

    public bool showMain = true;
    public bool showSub = false;

    public int gridSizeX;
    public int gridSizeY;
    public int gridSizeZ;

    public float smallStep;
    public float largeStep;

    public float startX;
    public float startY;
    public float startZ;

    private Material lineMaterial;

    public  Color mainColor = new Color(0f, 1f, 0f, 1f);
    public Color subColor = new Color(0f, 0.5f, 0f, 1f);

    void CreateLineMaterial()
    {
        if (!lineMaterial)
        {
            // Unity has a built-in shader that is useful for drawing
            // simple colored things.
            var shader = Shader.Find("Hidden/Internal-Colored");
            lineMaterial = new Material(shader);
            lineMaterial.hideFlags = HideFlags.HideAndDontSave;
            // Turn on alpha blending
            lineMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
            lineMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
            // Turn backface culling off
            lineMaterial.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Off);
            // Turn off depth writes
            lineMaterial.SetInt("_ZWrite", 0);
        }
    }

    void OnPostRender()
    {
        CreateLineMaterial();
        // set the current material
        lineMaterial.SetPass(0);

        GL.Begin(GL.LINES);

        if (showSub)
        {
            GL.Color(subColor);

            //Layers
            for (float j = 0; j <= gridSizeY; j += smallStep)
            {
                //X axis lines
                for (float i = 0; i <= gridSizeZ; i += smallStep)
                {
                    GL.Vertex3(startX, startY + j , startZ + i);
                    GL.Vertex3(startX + gridSizeX, startY + j , startZ + i);
                }

                //Z axis lines
                for (float i = 0; i <= gridSizeX; i += smallStep)
                {
                    GL.Vertex3(startX + i, startY + j , startZ);
                    GL.Vertex3(startX + i, startY + j , startZ + gridSizeZ);
                }
            }

            //Y axis lines
            for (float i = 0; i <= gridSizeZ; i += smallStep)
            {
                for (float k = 0; k <= gridSizeX; k += smallStep)
                {
                    GL.Vertex3(startX + k, startY , startZ + i);
                    GL.Vertex3(startX + k, startY + gridSizeY , startZ + i);
                }
            }
        }

        if (showMain)
        {
            GL.Color(mainColor);

            //Layers
            for (float j = 0; j <= gridSizeY; j += largeStep)
            {
                //X axis lines
                for (float i = 0; i <= gridSizeZ; i += largeStep)
                {
                    GL.Vertex3(startX, startY + j, startZ + i);
                    GL.Vertex3(startX + gridSizeX, startY + j , startZ + i);
                }

                //Z axis lines
                for (float i = 0; i <= gridSizeX; i += largeStep)
                {
                    GL.Vertex3(startX + i, startY + j , startZ);
                    GL.Vertex3(startX + i, startY + j , startZ + gridSizeZ);
                }
            }

            //Y axis lines
            for (float i = 0; i <= gridSizeZ; i += largeStep)
            {
                for (float k = 0; k <= gridSizeX; k += largeStep)
                {
                    GL.Vertex3(startX + k, startY , startZ + i);
                    GL.Vertex3(startX + k, startY + gridSizeY , startZ + i);
                }
            }
        }


        GL.End();
    }
}

I don’t have enough rep to edit Em3rgency’s post, but his solution requires a modification to render the colours correctly on Android–they will currently render as black.

I have changed CreateLineMaterial to GetLineMaterial and commented out the calls to GL.Color.

private IDictionary<Color, Material> materialsByColor = new Dictionary<Color, Material>();
private Material GetLineMaterial(Color color)
{
    		Material lineMaterial;
    		if( !materialsByColor.TryGetValue(color, out lineMaterial) ) 
    		{
    			lineMaterial = new Material( "Shader \"Lines/Colored Blended\" {" +
    			                            " Properties { _Color (\"Main Color\", Color) = ("+color.r+","+color.g+","+color.b+","+color.a+") } " +
    			                            " SubShader { Pass { " +
    			                            " Blend SrcAlpha OneMinusSrcAlpha " +
    			                            " ZWrite Off Cull Off Fog { Mode Off } " +
    			                            " Color[_Color] " +
    			                            " BindChannels {" +
    			                            " Bind \"vertex\", vertex Bind \"color\", color }" +
    			                            "} } }" );

    			lineMaterial.hideFlags = HideFlags.HideAndDontSave;
    			lineMaterial.shader.hideFlags = HideFlags.HideAndDontSave;
    
    			materialsByColor.Add(color, lineMaterial);
    		}
    		return lineMaterial;
}

I then call it like so:

GL.Begin( GL.LINES );
if(showSub)
{
    //GL.Color(subColor);
    var lineMaterial = GetLineMaterial(subColor);
    lineMaterial.SetPass( 0 );

An easier way to do it is to use a tiled material:

  1. Create and import an square image with a transparent background and a solid square frame around the edge.

  2. Create a material, set it’s shader to “Transparent/Diffuse”, and drag your image onto it.

  3. Set the “Tiling” fields of the material to your grid dimensions.

  4. Create a Quad GameObject, scale it to whatever size you want the grid to be, and attach the material to it.

to make colors to display properly in Unity5 you need to modify CreateLineMaterial():

	void CreateLineMaterial()
	{
		if(!lineMaterial)
		{
			// Unity has a built-in shader that is useful for drawing
			// simple colored things.
			var shader = Shader.Find("Hidden/Internal-Colored");
			lineMaterial = new Material(shader);
			lineMaterial.hideFlags = HideFlags.HideAndDontSave;
			// Turn on alpha blending
			lineMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
			lineMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
			// Turn backface culling off
			lineMaterial.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Off);
			// Turn off depth writes
			lineMaterial.SetInt("_ZWrite", 0);
		}
	}

I had the need to be able to move the grid after the original placement so I added a little code to @Em3rgency’s script to allow me to move the grid around. This code also includes the small addition to prevent the infinite loops while modifying small Step and Large Step variables.

using UnityEngine;
using System.Collections;

public class gridOverlay : MonoBehaviour {
	
	public GameObject plane;
	
	public bool showMain = true;
	public bool showSub = false;
	
	public int gridSizeX;
	public int gridSizeY;
	public int gridSizeZ;
	
	public float smallStep;
	public float largeStep;
	
	public float startX;
	public float startY;
	public float startZ;

	public float transformX;
	public float transformY;
	public float transformZ;
	
	private float offsetY = 0;
	private float scrollRate = 0.1f;
	private float lastScroll = 0f;
	
	private Material lineMaterial;
	
	private Color mainColor = new Color(0f,1f,0f,1f);
	private Color subColor = new Color(0f,0.5f,0f,1f);
	
	void Start () 
	{
   	}
	
	void Update () 
	{


		if(lastScroll + scrollRate < Time.time)
		{
			if(Input.GetKey(KeyCode.KeypadPlus)) 
			{
				plane.transform.position = new Vector3(plane.transform.position.x, plane.transform.position.y + smallStep, plane.transform.position.z);
				offsetY += smallStep;
				lastScroll = Time.time;
			}
			if(Input.GetKey(KeyCode.KeypadMinus))
			{
				plane.transform.position = new Vector3(plane.transform.position.x, plane.transform.position.y - smallStep, plane.transform.position.z);
				offsetY -= smallStep;
				lastScroll = Time.time;
			}
		}
	}
	
	void CreateLineMaterial() 
	{
		
		if( !lineMaterial ) {
			lineMaterial = new Material( "Shader \"Lines/Colored Blended\" {" +
			                            "SubShader { Pass { " +
			                            "    Blend SrcAlpha OneMinusSrcAlpha " +
			                            "    ZWrite Off Cull Off Fog { Mode Off } " +
			                            "    BindChannels {" +
			                            "      Bind \"vertex\", vertex Bind \"color\", color }" +
			                            "} } }" );
			lineMaterial.hideFlags = HideFlags.HideAndDontSave;
			lineMaterial.shader.hideFlags = HideFlags.HideAndDontSave;}
	}
	
	void OnPostRender() 
	{        
		CreateLineMaterial();
		// set the current material
		lineMaterial.SetPass( 0 );
		
		GL.Begin( GL.LINES );
		if (smallStep <= 0)
			smallStep = 1;

		if (largeStep <= 0)
			largeStep = 1;

		if(showSub)
		{
			GL.Color(subColor);
			
			//Layers
			for(float j = 0; j <= gridSizeY; j += smallStep)
			{
				//X axis lines
				for(float i = 0; i <= gridSizeZ; i += smallStep)
				{
					GL.Vertex3( startX + transformX, j + offsetY + transformY, startZ + i + transformZ);
					GL.Vertex3( gridSizeX + transformX, j + offsetY + transformY, startZ + i + transformZ);
				}
				
				//Z axis lines
				for(float i = 0; i <= gridSizeX; i += smallStep)
				{
					GL.Vertex3( startX + i + transformX, j + offsetY + transformY, startZ + transformZ);
					GL.Vertex3( startX + i + transformX, j + offsetY + transformY, gridSizeZ + transformZ);
				}
			}
			
			//Y axis lines
			for(float i = 0; i <= gridSizeZ; i += smallStep)
			{
				for(float k = 0; k <= gridSizeX; k += smallStep)
				{
					GL.Vertex3( startX + k + transformX, startY + offsetY + transformY, startZ + i + transformZ);
					GL.Vertex3( startX + k + transformX, gridSizeY + offsetY + transformY, startZ + i + transformZ);
				}
			}
		}
		
		if(showMain)
		{
			GL.Color(mainColor);
			
			//Layers
			for(float j = 0; j <= gridSizeY; j += largeStep)
			{
				//X axis lines
				for(float i = 0; i <= gridSizeZ; i += largeStep)
				{
					GL.Vertex3( startX + transformX, j + offsetY + transformY, startZ + i + transformZ);
					GL.Vertex3( gridSizeX + transformX, j + offsetY + transformY, startZ + i + transformZ);
				}
				
				//Z axis lines
				for(float i = 0; i <= gridSizeX; i += largeStep)
				{
					GL.Vertex3( startX + i + transformX, j + offsetY + transformY, startZ + transformZ);
					GL.Vertex3( startX + i + transformX, j + offsetY + transformY, gridSizeZ + transformZ);
				}
			}
			
			//Y axis lines
			for(float i = 0; i <= gridSizeZ; i += largeStep)
			{
				for(float k = 0; k <= gridSizeX; k += largeStep)
				{
					GL.Vertex3( startX + k + transformX, startY + offsetY + transformY, startZ + i + transformZ);
					GL.Vertex3( startX + k + transformX, gridSizeY + offsetY + transformY, startZ + i + transformZ);
				}
			}
		}
		
		
		GL.End();
	}
}

in my case, my unity freeze when i pressed play button;
i suspect because the code does not handle for floating points? (i used the same parameter as mentioned below)

idk but i modified the code, here is what i used,worked fine with floating points(i use parameter gridsize 29x18 with 0.46 small step and 0.92 large step). I added offset on X axis aswell.

using UnityEngine;
using System.Collections;

public class ShowGrid : MonoBehaviour {


    public bool showMain = true;
    public bool showSub = false;

    public float gridSizeX;
    public float gridSizeY;

    public float smallStep;
    public float largeStep;

    public float startX;
    public float startY;

    public float offsetY;
    public float offsetX;

    private Material lineMaterial;

    private Color mainColor = new Color(0f, 1f, 0f, 1f);
    private Color subColor = new Color(0f, 0.5f, 0f, 1f);

    void Start()
    {

        gridSizeX *= smallStep;
        gridSizeY *= smallStep;
    }

    void Update()
    {
    }

    void CreateLineMaterial()
    {

        if (!lineMaterial)
        {
            lineMaterial = new Material("Shader \"Lines/Colored Blended\" {" +
                "SubShader { Pass { " +
                "    Blend SrcAlpha OneMinusSrcAlpha " +
                "    ZWrite Off Cull Off Fog { Mode Off } " +
                "    BindChannels {" +
                "      Bind \"vertex\", vertex Bind \"color\", color }" +
                "} } }");
            lineMaterial.hideFlags = HideFlags.HideAndDontSave;
            lineMaterial.shader.hideFlags = HideFlags.HideAndDontSave;
        }
    }

    void OnPostRender()
    {
        CreateLineMaterial();
        // set the current material
        lineMaterial.SetPass(0);
        GL.Begin(GL.LINES);

        if (showSub)
        {
            GL.Color(subColor);

            //Layers
            for (float j = 0; j <= gridSizeY; j += smallStep)
            {
                //X axis lines
                    GL.Vertex3(startX + offsetX, j + offsetY, 0);
                    GL.Vertex3(gridSizeX + offsetX, j + offsetY, 0);
            }

            //Y axis lines
                for (float k = 0; k <= gridSizeX; k += smallStep)
                {
                    GL.Vertex3(startX + k + offsetX, startY + offsetY, 0);
                    GL.Vertex3(startX + k + offsetX, gridSizeY + offsetY, 0);
                }
            
        }

        if (showMain)
        {
            GL.Color(mainColor);

            //Layers
            for (float j = 0; j <= gridSizeY; j += largeStep)
            {
                //X axis lines
                    GL.Vertex3(startX + offsetX, j + offsetY, 0);
                    GL.Vertex3(gridSizeX + offsetX, j + offsetY, 0);
            }

            //Y axis lines
                for (float k = 0; k <= gridSizeX; k += largeStep)
                {
                    GL.Vertex3(startX + k + offsetX, startY + offsetY, 0);
                    GL.Vertex3(startX + k + offsetX, gridSizeY + offsetY, 0);
                }
        }


        GL.End();
    }
}

hope this helps

I had some specific needs for our app, so with help from the other answers posted above, composed below in case anyone benefits from it. Some context: I wanted one white and one contrasting black “shadow” line for each line, so as to make it visible on any background; the script is added and destroyed to the camera when a setting is toggled, so there’s no additional doShow bool or such; the center of the grid follows the camera as one (vr)-teleports around, rounding to 1 meter for the grid size; there is a small indicator at half a meter for each line; lines fade out a bit towards the edge.

using UnityEngine;

public class GridLines : MonoBehaviour {

    const float stretch = 0.495f;
    const float max = 2f;
    const float step = 1f;
    Material lineMaterial;
    bool[] trueFalse = new bool[] {true, false};
        
    void Start() {
        var shader = Shader.Find("Hidden/Internal-Colored");
        lineMaterial = new Material(shader);
        lineMaterial.hideFlags = HideFlags.HideAndDontSave;
        lineMaterial.SetInt( "_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha );
        lineMaterial.SetInt( "_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha );
        lineMaterial.SetInt( "_Cull", (int)UnityEngine.Rendering.CullMode.Off );
        lineMaterial.SetInt("_ZWrite", 0);
    }

    void OnPostRender() {
        Vector3 start = new Vector3(
            Mathf.Round(transform.position.x),
            Mathf.Round(transform.position.y),
            Mathf.Round(transform.position.z)
        );
        
        lineMaterial.SetPass(0);
        GL.Begin(GL.LINES);

        foreach (bool isWhite in trueFalse) {
            if (!isWhite) {
                const float offset = 0.0015f;
                start = new Vector3(start.x + offset, start.y - offset, start.z + offset);
            }
                
            foreach (bool drawEdge in trueFalse) {
                float alpha = drawEdge ? 0.1f : 0.75f;
                float tone = isWhite ? 1f : 0f;
                GL.Color( new Color(tone, tone, tone, alpha) );

                for (float x = -max; x <= max; x += step) {
                    for (float y = -max; y <= max; y += step) {
                        for (float z = -max; z <= max; z += step) {
                            
                            bool isEdge = Mathf.Abs(x) == max || Mathf.Abs(y) == max || Mathf.Abs(z) == max;
                            if ( (isEdge && drawEdge) || (!isEdge && !drawEdge) ) {
                                GL.Vertex3(start.x + x - stretch, start.y + y, start.z + z);
                                GL.Vertex3(start.x + x + stretch, start.y + y, start.z + z);

                                GL.Vertex3(start.x + x, start.y + y - stretch, start.z + z);
                                GL.Vertex3(start.x + x, start.y + y + stretch, start.z + z);
                                
                                GL.Vertex3(start.x + x, start.y + y, start.z + z - stretch);
                                GL.Vertex3(start.x + x, start.y + y, start.z + z + stretch);
                            }

                        }
                    }
                    
                }
            }
            
        }

        GL.End();
    }

}