Tips & Tricks

Helpful tips and tricks for working in Unity.

Snap GameObject to floor/surface/vertex

Select a GameObject with the Move Tool W, then hold V.

  • Snap vertex to vertex - Drag the square over any vertex.
  • Snap vertex to vertex (with rounded position numbers) - Drag the square over any vertex while holding Ctrl.
  • Snap vertex to surface - Drag the square over any surface while holding Ctrl-Shift.

Attributes

Attributes are placed above variables/functions. Here are some useful ones.

Header allows the inspector to display a title/header above variables.

[Header("Info")]
public string _name;
public string _description;

[Header("Settings")]
public int _width;
public int _height;

TextArea

Multiline

HideInInspector

Serializes a field, but will not show it in the inspector.

[HideInInspector]
private int _varName;

Range

[Range(0, 100)]
public int _limitedRange;

SerializeField

Allows private fields to show in the inspector:

[SerializeField]
private int _maxHealth = 100;

Including auto-generated backing fields for Properties:

[field: SerializeField]
private int MaxHealth { get; set; }

ContextMenu

ContextMenu allows you to run a function by right-clicking on a Component in the inspector.

[ContextMenu("Name")]
void FunctionName()
{
	...
}

ContextMenuItem

ContextMenuItem allows you to run a function by right-clicking on a variable/field in the inspector.

[ContextMenuItem("Reset", "ResetBiography")]
public string playerBiography = "";

void ResetBiography()
{
	playerBiography = "";
}

MenuItem allows you to run a function from an editor dropdown menu or hotkey.

[MenuItem ("MyMenu/Do Something")]
static void DoSomething()
{
	...
}

CreateAssetMenu

Creates a ScriptableObject asset on disk. It can store data and be used like a profile.

[CreateAssetMenu(fileName = "GraphicsSetting", menuName = "MyGame/Graphics Setting", order = 1)]
public class GraphicsSettingsData : ScriptableObject {

	[Header("Info")]
	public string _name;
	public string _description;
	
	[Header("Settings")]
	public bool _bloomEnabled;
	public bool _ambientOcclusionEnabled;
	public bool _antialiasingEnabled;

}

SelectionBase

Allows you to select this GameObject in the scene instead of a child.

[SelectionBase]
public class Script : MonoBehaviour { }

Attribute Extensions

Logs

Here are some cool things you can do with Debug.Log and the Console.

Single-line console log entries with timestamps

You can reduce the size of console (Window > General > Console) entries by clicking the 3 dots in the top-right and choosing Log Entry > 1 line.

Show Timestamp is also useful.

Formatting

Use Rich Text for formatting.

Debug.Log("<b><color=red>Red and Bold!</color></b>");

Line break / New Line

Use \n to create a new line.

Debug.Log("First Line\nSecond Line");

Highlight GameObject in hierarchy

When selecting a log entry, you can highlight the GameObject it came from.

Debug.Log("Hello World!", gameObject);

Shortcut to add/subtract or increment/decrement

public int number = 10;

// Full (adds one to variable)
number = number + 1;

// Shortened
number += 1;

// Shortest
number++;

Save / Load object selection in hierarchy and project view

Ctrl + Alt + (Number) = Save selection Ctrl + Shift + (Number) = Load selection

It works with GameObjects and Assets, including mixing the two.

Save content from play mode in edit mode

  • Play your game, make changes.
  • Right-click and Copy the gameobject(s) you want to save.
  • Stop playing, right-click in hierarchy and Paste.

The same also works for modified components.

Hierarchy - Expand/Collapse All

  • Hold left-alt when clicking an arrow to expand/collapse all of the children of a GameObject.

Inspector - Expressions

Number fields support math expressions. Typing 1+1 then enter will output 2.

Function support - sqrt, sin, cos, tan, floor, ceil, round.

Distribution over multi-selection (L, R) and can refer to current value to change it across multi-selection (+=3, *=2).

Developer Tweet

Inspector - Show auto-properties

You can now use [field: SerializeField] to show auto-implemented properties in Unity’s inspector.

[SerializeField] // Show private field in inspector.
private int number;

[field: SerializeField] // Show property in inspector.
public string MyProperty { get; set; }

Physics - OnTrigger/OnCollision called on parent only

If a parent GameObject contains a Rigidbody component and a Component with an OnTrigger/OnCollision function, child Colliders will call the function on the parent.

This allows Compound Colliders and allows you to keep all of your scripts on the parent/root GameObject.

TryGetComponent vs GetComponent

TryGetComponent can reduce lines of code and avoid allocations in the editor.

Old code:

var test = enemy.GetComponent<TestComponent>();

if (test != null)
{
	test.Function();
}

New code (Unity 2019.2 or higher):

if (enemy.TryGetComponent<TestComponent>(out var test))
{
	test.Function();
}

TryGetComponent returns true or false, but also gives you the component as a reference via the out parameter.

C#7 allows you to inline the out variable.