Getting Started with Unity Gizmos: A Powerful Tool for Visualizing Debug Info in the Scene View

Created: 2026-02-05Last updated: 2026-07-13

Learn how to use Unity's Gizmos to visualize debug information in the Scene view. Display empty GameObjects, trigger areas, AI detection ranges, and more.

Tested with: Unity 2022.3 LTS / Unity 6

"I can't tell where my empty GameObjects are..." "I want to see how far my trigger reaches..." "I want to tweak my AI's detection range while actually seeing it..."

That's where Gizmos come in. Gizmos are a tool that draws shapes in the Scene view to make debug information visible. Once detection ranges and paths you used to tune by squinting at numbers become visible shapes in the Scene view, your iteration speed goes way up.

Conceptual image of Gizmos. A clay-style game scene with glowing wireframe spheres and line guides overlaid

What You'll Learn

  • When to use OnDrawGizmos vs. OnDrawGizmosSelected
  • How to decide between Gizmos, Debug.Draw, and Handles
  • Five practical recipes: AI detection ranges, paths, trigger areas, and more
  • How to build an "enemy AI debug view" that draws patrol routes, vision, and attack ranges in one screen

Sponsored

Basic Usage of Gizmos

There are two event functions that serve as your entry points for drawing. Choose based on whether you want the gizmo visible at all times or only when the object is selected.

Comparison of OnDrawGizmos and OnDrawGizmosSelected. On the left, ranges for all objects are always visible; on the right, only the selected object's range is shown

OnDrawGizmos: Always Draw Gizmos

using UnityEngine;

public class GizmosExample : MonoBehaviour
{
    void OnDrawGizmos()
    {
        // Draw a yellow sphere
        Gizmos.color = Color.yellow;
        Gizmos.DrawSphere(transform.position, 1.0f);
    }
}

OnDrawGizmosSelected: Draw Gizmos Only When Selected

void OnDrawGizmosSelected()
{
    // Draw a red sphere
    Gizmos.color = Color.red;
    Gizmos.DrawSphere(transform.position, 1.0f);
}

Combining Both

void OnDrawGizmos()
{
    // Green when not selected
    Gizmos.color = Color.green;
    Gizmos.DrawSphere(transform.position, 1.0f);
}

void OnDrawGizmosSelected()
{
    // Red when selected
    Gizmos.color = Color.red;
    Gizmos.DrawSphere(transform.position, 1.0f);
}

Which Tool Draws It? Gizmos vs. Debug.Draw vs. Handles

Gizmos aren't the only way to draw things in the Scene view. Sorting the three tools by "when and where they're visible" up front makes the method list that follows much easier to navigate.

GizmosDebug.DrawHandles
Where you write itOnDrawGizmos familyRegular code such as UpdateEditor scripts
When it's visibleIn edit mode and at runtimeOnly while playingIn edit mode (editor extensions)
What it can doDisplay shapesDisplay lines and rays (with an optional duration)Edit values by dragging

Note: Both Gizmos and Debug.Draw appear in the Scene view. To see them in the Game view as well, turn on the "Gizmos" button in the top-right corner of the Game view. None of them appear in a built game.

Debug.Draw Example

void Update()
{
    // Draw a ray at runtime (red, visible for 1 second)
    Debug.DrawRay(transform.position, transform.forward * 10f, Color.red, 1f);

    // Draw a line between two points
    Debug.DrawLine(pointA, pointB, Color.green);
}

Rule of thumb: Things you want to see constantly from the placement and tuning stage — detection ranges, triggers — belong to Gizmos. Things you only need to check at the moment they happen — like raycast trajectories — belong to Debug.Draw. Handles live in the world of editor extensions, so we only touch on them in the bonus section.

Main Methods of the Gizmos Class (Reference)

What follows is a list of drawing methods. You don't need to memorize them all — skim it to see what kinds of shapes are possible, and come back whenever you need one.

Gallery of Gizmos drawing methods, showing the shapes you can draw with DrawSphere, DrawWireSphere, DrawCube, DrawWireCube, DrawLine, and DrawRay
MethodDescription
Gizmos.colorSet the drawing color
Gizmos.DrawSphereDraw a solid sphere
Gizmos.DrawWireSphereDraw a wireframe sphere
Gizmos.DrawCubeDraw a solid cube
Gizmos.DrawWireCubeDraw a wireframe cube
Gizmos.DrawLineDraw a line between two points
Gizmos.DrawRayDraw a ray
Gizmos.DrawIconDraw an icon
Gizmos.DrawMeshDraw a mesh
Gizmos.matrixSet the transformation matrix

Usage Examples

// Draw a sphere
Gizmos.color = Color.red;
Gizmos.DrawSphere(transform.position, 1.0f);

// Draw a wireframe cube
Gizmos.color = Color.yellow;
Gizmos.DrawWireCube(transform.position, new Vector3(2, 2, 2));

// Draw a line
Gizmos.color = Color.blue;
Gizmos.DrawLine(transform.position, transform.position + Vector3.forward * 5);

// Draw a ray
Gizmos.DrawRay(transform.position, transform.forward * 5);

Semi-Transparent Drawing

By using a Color with an alpha value, you can draw semi-transparent Gizmos.

// Semi-transparent red (alpha 0.3)
Gizmos.color = new Color(1f, 0f, 0f, 0.3f);
Gizmos.DrawSphere(transform.position, 2.0f);

// Draw the outline fully opaque
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, 2.0f);

Combining a fill with an outline makes the area much easier to read.

Sponsored

Practical Examples

Example 1: Visualizing an Empty GameObject

public class EmptyObjectGizmo : MonoBehaviour
{
    [SerializeField] private Color normalColor = Color.green;
    [SerializeField] private Color selectedColor = Color.red;
    [SerializeField] private float radius = 0.5f;

    void OnDrawGizmos()
    {
        Gizmos.color = normalColor;
        Gizmos.DrawSphere(transform.position, radius);
    }

    void OnDrawGizmosSelected()
    {
        Gizmos.color = selectedColor;
        Gizmos.DrawSphere(transform.position, radius);
    }
}

Example 2: Visualizing a Trigger Area

public class TriggerGizmo : MonoBehaviour
{
    [SerializeField] private BoxCollider boxCollider;

    void OnDrawGizmos()
    {
        if (boxCollider == null) return;

        Gizmos.color = Color.green;
        Gizmos.matrix = transform.localToWorldMatrix;
        Gizmos.DrawWireCube(boxCollider.center, boxCollider.size);
    }
}

Example 3: Visualizing an AI Detection Range

A "detection radius of 10" that's hard to grasp from numbers alone becomes a visible wire sphere in the Scene view. The big win is being able to tune the range on the spot while placing enemies.

Example of AI detection range Gizmos. A clay-style enemy robot is surrounded by a yellow wireframe sphere, making the detection range obvious at a glance. It has noticed a player who entered the range
public class AIDetectionGizmo : MonoBehaviour
{
    [SerializeField] private float detectionRange = 10.0f;

    void OnDrawGizmos()
    {
        Gizmos.color = Color.yellow;
        Gizmos.DrawWireSphere(transform.position, detectionRange);
    }

    void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(transform.position, detectionRange);
        // Show the forward direction as a line
        Gizmos.DrawRay(transform.position, transform.forward * detectionRange);
    }
}

Example 4: Visualizing a Path

public class PathGizmo : MonoBehaviour
{
    [SerializeField] private Transform[] waypoints;

    void OnDrawGizmos()
    {
        if (waypoints == null || waypoints.Length < 2) return;

        Gizmos.color = Color.cyan;

        // Show waypoints as spheres
        foreach (var waypoint in waypoints)
        {
            if (waypoint != null)
                Gizmos.DrawSphere(waypoint.position, 0.3f);
        }

        // Connect waypoints with lines
        for (int i = 0; i < waypoints.Length - 1; i++)
        {
            if (waypoints[i] != null && waypoints[i + 1] != null)
                Gizmos.DrawLine(waypoints[i].position, waypoints[i + 1].position);
        }
    }
}

Example 5: Debugging Raycasts

public class RaycastGizmo : MonoBehaviour
{
    [SerializeField] private float rayDistance = 10.0f;

    void OnDrawGizmos()
    {
        // Show the raycast direction as a line
        Gizmos.color = Color.red;
        Gizmos.DrawRay(transform.position, transform.forward * rayDistance);

        // Show a sphere at the hit position
        if (Physics.Raycast(transform.position, transform.forward, out RaycastHit hit, rayDistance))
        {
            Gizmos.color = Color.green;
            Gizmos.DrawSphere(hit.point, 0.2f);
        }
    }
}

Performance note: Running Physics.Raycast inside OnDrawGizmos can slow down the editor if the script is attached to many objects. Keep it strictly for debugging, and prefer OnDrawGizmosSelected (which only runs while selected) in production projects.

Sponsored

Showing and Hiding Gizmos

Click the "Gizmos" button in the top-right corner of the Scene view to open the Gizmos menu.

  • Toggle Gizmos visibility per component
  • Adjust Gizmos size with the "3D Icons" slider
  • Gizmos can be shown in both the Scene view and the Game view

Showing Gizmos in the Game View

Turn on the "Gizmos" button in the top-right corner of the Game view, and Gizmos will also appear in the editor's Game view. This comes in handy while debugging.

About builds: OnDrawGizmos is never called in a built game, but the method itself is still compiled into the build as IL (intermediate language). This is practically harmless, but if you want to strictly exclude it from the build, wrap it in #if UNITY_EDITOR.

#if UNITY_EDITOR
void OnDrawGizmos()
{
    Gizmos.color = Color.yellow;
    Gizmos.DrawSphere(transform.position, 1.0f);
}
#endif

Bottom line: Skipping #if UNITY_EDITOR is fine in most cases and has no performance impact. Use it only when you want to make the code's intent explicit or need strict control over build size.

Best Practices

  • Use OnDrawGizmos and OnDrawGizmosSelected appropriately - Choose between always-visible and selected-only display
  • Use distinct colors - For example, green for normal, red for selected, yellow for warnings
  • Expose settings with SerializeField - Let colors and sizes be tweaked in the Inspector
  • Don't forget null checks - Prevent errors when references are null
  • Take advantage of Gizmos.matrix - Handle rotated and scaled objects correctly
[SerializeField] private BoxCollider boxCollider;
[SerializeField] private Color gizmoColor = Color.green;

void OnDrawGizmos()
{
    if (boxCollider == null) return;

    Gizmos.matrix = transform.localToWorldMatrix;
    Gizmos.color = gizmoColor;
    Gizmos.DrawWireCube(boxCollider.center, boxCollider.size);
}

Hands-On: Build an Enemy AI Debug View in One Screen

To wrap up, let's combine the drawing methods above into a single "AI debug view." The example is a patrolling enemy in a top-down action game, but the same idea works for a guard in a stealth game or a turret in a tower defense.

The key is to split "when to draw" by the nature of each piece of information.

  • Always visible (OnDrawGizmos): the patrol route — information you want to survey across the whole level, even with no enemy selected
  • Selected only (OnDrawGizmosSelected): detection range, attack range, and vision cone — per-enemy details that would clutter the screen if every enemy drew them at once
  • Play mode only: a line to the current destination — runtime information about where the enemy is actually headed
Finished enemy AI debug view. A yellow detection range and red attack range surround the enemy, a cyan patrol route is drawn on the floor, and a magenta destination line pierces a wall toward the hiding player
using UnityEngine;

public class EnemyPatrol : MonoBehaviour
{
    [Header("AI Settings")]
    [SerializeField] private Transform[] patrolPoints;
    [SerializeField] private Transform player;
    [SerializeField] private float detectionRange = 6f;
    [SerializeField] private float attackRange = 1.5f;
    [SerializeField] private float viewAngle = 90f;
    [SerializeField] private float moveSpeed = 3f;

    private int patrolIndex;
    private Vector3 currentDestination;

    void Update()
    {
        if (patrolPoints == null || patrolPoints.Length == 0) return;

        // Detection: distance only (deliberately ignores view angle and walls)
        bool playerFound = player != null &&
            Vector3.Distance(transform.position, player.position) <= detectionRange;

        currentDestination = playerFound
            ? player.position
            : patrolPoints[patrolIndex].position;

        // Move toward the destination; advance to the next patrol point on arrival
        transform.position = Vector3.MoveTowards(
            transform.position, currentDestination, moveSpeed * Time.deltaTime);

        if (!playerFound &&
            Vector3.Distance(transform.position, currentDestination) < 0.1f)
        {
            patrolIndex = (patrolIndex + 1) % patrolPoints.Length;
        }
    }

    // Always visible: patrol route, plus the destination while playing
    void OnDrawGizmos()
    {
        if (patrolPoints == null || patrolPoints.Length == 0) return;

        Gizmos.color = Color.cyan;
        for (int i = 0; i < patrolPoints.Length; i++)
        {
            if (patrolPoints[i] == null) continue;
            Gizmos.DrawSphere(patrolPoints[i].position, 0.3f);

            var next = patrolPoints[(i + 1) % patrolPoints.Length];
            if (next != null)
                Gizmos.DrawLine(patrolPoints[i].position, next.position);
        }

        // Play mode only: where is it headed right now? (this line is the star of bug hunting)
        if (Application.isPlaying)
        {
            Gizmos.color = Color.magenta;
            Gizmos.DrawLine(transform.position, currentDestination);
        }
    }

    // Selected only: this enemy's own ranges
    void OnDrawGizmosSelected()
    {
        // Detection range (yellow) and attack range (red)
        Gizmos.color = Color.yellow;
        Gizmos.DrawWireSphere(transform.position, detectionRange);
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(transform.position, attackRange);

        // Draw the intended vision cone as two edge lines
        Gizmos.color = Color.yellow;
        Vector3 left = Quaternion.Euler(0, -viewAngle / 2f, 0) * transform.forward;
        Vector3 right = Quaternion.Euler(0, viewAngle / 2f, 0) * transform.forward;
        Gizmos.DrawRay(transform.position, left * detectionRange);
        Gizmos.DrawRay(transform.position, right * detectionRange);
    }
}

Place two to four empty GameObjects, register them in patrolPoints, and press Play. The enemy patrols along the cyan route and chases the player when they get close.

Symptom: The Enemy Runs at a Player Behind a Wall

Play with this AI for a while and you'll hit a moment where the player is hiding behind a wall, yet the enemy keeps running straight at it. Before staring at the code, look at the Scene view.

  • The magenta destination line pierces the wall and pins the player → the enemy is chasing a player it "thinks" it can see
  • Select the enemy, and it's chasing a player outside the yellow vision cone lines → the view angle isn't being used either

In other words, you can isolate the cause — "detection is distance-only and ignores both view angle and cover" — without reading a single line of code. That's Gizmos at their best. The fixes have their own articles: vision cones with occlusion checks in building enemy vision and detection, and wall checks in our Physics.Raycast guide.

As a last check, try switching off the "Gizmos" button in the top-right of the Scene view. The shapes vanish — and the enemy keeps moving as if nothing happened. Drawing is only "information for your eyes"; the decisions live in Update. With that separation in place, the shapes snap to every Inspector tweak, and even ten enemies leave the screen perfectly readable.

Bonus: Good to Know for Later

Once you're comfortable with Gizmos, these are the natural next steps.

  • The Handles class, which lets you drag values: Gizmos are display-only, but with Handles you can build interactive controls — like dragging in the Scene view to expand a detection range. This lives in the world of custom editors placed in an Editor folder, so it pairs well with our intro to editor extensions.

    FeatureGizmosHandles
    Where it livesRegular scriptsEditor folder
    InteractionDisplay onlyValues can be changed by dragging
    PurposeDebug displayCustom editor tools
  • Combine with raycast visualization: The raycast visualization in Example 5 ties directly into our Physics.Raycast article. For "my ray isn't hitting anything" bugs, visualizing first is the fastest path to a fix.

  • Know when to use logs instead: Spatial information like positions, ranges, and paths suits Gizmos, while temporal information like value changes and control flow suits Debug.Log. We cover logging techniques in our intro to debugging.

Summary

Gizmos are a powerful tool for visualizing debug information in the Scene view.

  • Visualize empty GameObjects - Makes their positions easy to spot
  • Show trigger and collider areas - Makes checking hitboxes easy
  • Show AI detection ranges - Tune parameters visually
  • Show paths and waypoints - Makes verifying movement routes easy
  • Debug raycasts - Visually confirm hit detection

Spatial information — positions, ranges, routes — is far easier to grasp drawn on screen than logged as numbers. Why not start by adding a single OnDrawGizmosSelected to the enemy or trigger you're building right now?

Further Reading