in Programming, Tutorial, Unity

How to Snap to Grid in Unity3D

Despite Unity3D being such an advanced framework, I am sometimes puzzled by its lack of basic features. Especially when working with 2D games, the lack of a proper snap to grid option is simply crazy. Luckily, Unity3D allows to extend its basic interface to add new behaviours. This post will explain how to add a customisable snap to grid option to your objects. Two different implementations are presented; the first one, despite being more complicated, could be used a good starting point to further extend and customise the inspector.

Step 1: The MonoBehaviour

Broadly speaking, the idea is to create a script which will force the position of the GameObject it’s attached to stick to integer multiples of a certain value. The twist is that we want this script to be executed only in the editor and to not cause any overhead during the execution of the game.

snap

The first step is to create a MonoBehaviour which is, de facto, doing nothing. It’s purpose is to help us configuring the snap properties for the GameObject it will be attached to.

using UnityEngine;
using System.Collections;

public class SnapToGrid : MonoBehaviour {
#if UNITY_EDITOR
    public bool snapToGrid = true;
    public float snapValue = 0.5f;

    public bool sizeToGrid = false;
    public float sizeValue = 0.25f;
#endif
}

As you can notice, this script will be able to snap not just the position, but also the size of its GameObject. Line 5 and line 11 makes these variables disappearing during the actual compilation of the game. By doing this, any release version will only have an empty script attached, causing little to no overhead.

Step 2: The Editor script

The SnapToGrid script does nothing. Literally, nothing. The actual code is contained in a script called SnapToGridEditor which has to be contained in a folder called Editor.

using UnityEngine;
using UnityEditor;
using System.Collections;

[InitializeOnLoad]
[CustomEditor(typeof(SnapToGrid), true)]
[CanEditMultipleObjects]
public class SnapToGridEditor : Editor {
	
	public override void OnInspectorGUI()
	{
		base.OnInspectorGUI();
		
		SnapToGrid actor = target as SnapToGrid;
		if (actor.snapToGrid)
			actor.transform.position = RoundTransform (actor.transform.position, actor.snapValue);

		if (actor.sizeToGrid)
			actor.transform.localScale = RoundTransform(actor.transform.localScale, actor.sizeValue);
	}
	
        // The snapping code
	private Vector3 RoundTransform (Vector3 v, float snapValue)
	{
		return new Vector3
		(
			snapValue * Mathf.Round(v.x / snapValue),
			snapValue * Mathf.Round(v.y / snapValue),
			v.z
		);
	}
}

Line 6 indicates that SnapToGridEditor should affect all the MonoBehaviours of SnapToGrid type. Unity will then execute OnInspectorGUI every time the inspector of a SnapToGrid script is selected. Line 14 is where the SnapToGrid script is accessed. Lines 23-31 changes a Vector3 according to the desired snap value; these scripts are intended for 2D, so that’s why the Z axis is never changed.

An alternative approach

For something as simple as adding snap to grid behaviour to your GameObjects, you could actually implement everything directly in the Update function of SnapToGrid.

using UnityEngine;
using System.Collections;

// This script is executed in the editor
[ExecuteInEditMode]
public class SnapToGrid : MonoBehaviour {
#if UNITY_EDITOR
    public bool snapToGrid = true;
    public float snapValue = 0.5f;

    public bool sizeToGrid = false;
    public float sizeValue = 0.25f;

    // Adjust size and position
    void Update ()
    {
    	if (snapToGrid)
			transform.position = RoundTransform (transform.position, snapValue);

		if (sizeToGrid)
			transform.localScale = RoundTransform(transform.localScale, sizeValue);
	}

 	// The snapping code
	private Vector3 RoundTransform (Vector3 v, float snapValue)
	{
		return new Vector3
		(
			snapValue * Mathf.Round(v.x / snapValue),
			snapValue * Mathf.Round(v.y / snapValue),
			v.z
		);
	}
#endif
}

Line 5 is necessary, since it will enable the script to be executed in the editor, while the game is not actually running.

Conclusion

Having scripts and editor scripts is quite a common pattern you’ll see in Unity3D. Such a separation allows also to change the appearance of the editor. This is particularly interesting if you need to add buttons or other custom behaviours to the inspector panel. As it often happens in Unity3D, there isn’t a single way to implement a feature. Another snap to grid script can be found here. For a guide oriented to Unity2D and snap to pixel, you can consult this link.

💖 Support this blog

This website exists thanks to the contribution of patrons on Patreon. If you think these posts have either helped or inspired you, please consider supporting this blog.

Patreon Patreon_button
Twitter_logo

YouTube_logo
📧 Stay updated

You will be notified when a new tutorial is released!

📝 Licensing

You are free to use, adapt and build upon this tutorial for your own projects (even commercially) as long as you credit me.

You are not allowed to redistribute the content of this tutorial on other platforms, especially the parts that are only available on Patreon.

If the knowledge you have gained had a significant impact on your project, a mention in the credit would be very appreciated. ❤️🧔🏻

Write a Comment

Comment

Webmentions

  • Sprite Doodle Shader Effect - Alan Zucconi

    […] has been covered already on this blog, in the article How To Snap To Grid. In that article, it was proposed a solution to the problem of snapping the position of an object […]

  • Tutorial Series - Alan Zucconi

    […] How to Snap to Grid in Unity3D […]

  • LCD Display Shader Effect – Alan Zucconi

    […] _Pixels values only. We have explored this already in a previous tutorial: How to Snap to Grid: […]