🤔 Unity, huh, how?

🤔

The debugger

The debugger is a tool that halts code execution. Values can be inspected, lines of code can be stepped over, and sometimes even modified. This does not require recompiling your code, or exiting Play Mode.

A functioning IDE is required, so first check IDE configuration if you are experiencing basic issues.

Rider attach Attaching

Your IDE needs to target a running application to start debugging. Usually this functionality is found in one of the top utility bars in an IDE's interface.

Attaching Rider's debugger

Attaching Rider to the Unity Editor

Rider breakpoint Breakpoints

Breakpoints are the entry point to a debugging session. Mark a line with a breakpoint and execution will halt when this line is reached if the debugger is attached.

Attaching Rider's debugger

A breakpoint in Rider

When execution is halted Unity will freeze, this is normal. You can now use the other debugger features of your IDE to assess problems. Rider stop debugging stop debugging to resume Unity's normal function, or Rider stop debugging resume to continue execution while remaining attached, ready to hit more breakpoints.

Managing breakpoints

Select the gutter for an executable line to add a breakpoint. Repeat the selection to remove it. You can Rider all breakpoints view all breakpoints to manage them in bulk, removing them all at once, or just finding forgotten ones.

Muting breakpoints

Often you want to continue testing with the debugger connected, without triggering breakpoints. You can Rider mute breakpoints mute breakpoints to stop them triggering without removing them. Individual breakpoints can also be Rider disabled breakpoint disabled.

Conditional breakpoints

Right-click a breakpoint and after adding a condition based on in-scope variables the breakpoint will become a Rider conditional breakpoint conditional breakpoint, and only trigger when the condition is met.

Conditional breakpoint in Rider

A conditional breakpoint in Rider

Note that conditional breakpoints halt execution to evaluate the condition, and this halting as a performance cost. In tight loops a conditional breakpoint may take too long to execute, and modifying the code to add the condition may be required. In these cases you may also prefer a tracepoint.

Rider tracepoint Tracepoints (logging breakpoints)

Disable the suspend execution setting of a Rider breakpoint breakpoint via the right-click menu so it becomes a Rider tracepoint tracepoint, navigate to more settings and add logging. The logs will print to the IDE's debug console, not Unity1.
Tracepoints are a great substitution for manual logging, avoiding unnecessary recompilation and Play Mode changes.

Rider data Variable inspection

Hovering over an initialised variable during debugging will provide you with a view of its internals. This lets you discover faulty logic or uninitialised values. Often a debugger will also allow you to hover an expression to evaluate its outcome (the result of an if statement for example).

Variable inspection in Rider

Inspecting a variable using Rider's debugger

Rider step over Stepping

Stepping through code is a way to continue execution line by line, optionally stepping into or over functions and properties. This gives information about program execution, testing false assumptions about branching behaviour or loops.

Name Description
Step over Step over Execute the line of code without entering functions.
Step into Step into Execute the line of code and enter any functions.
Step out Step out Execute until the function is exited.

Manually modifying the execution pointer

You can also skip to a part of code without running what's in-between by modifying the execution pointer.
Often this is done by dragging and dropping the pointer, or by running a Skip to Cursor command.

If you step over code accidentally, or miss something important, you can just go back and look!

Rider pause Pausing

Execution can be manually halted similar to a breakpoint, this is very helpful when debugging freezes caused by infinite loops. Just pause execution when the freeze occurs, and the debugger should lead you to the relevant section of code.

Rider watch Watches

Watches are tracked variables that persist across debugging sessions. While execution is halted via a breakpoint or pause, you can monitor the state of variables via the Watch window, similar to variable inspection.

You can add any variable or expression that is in scope as a watch, and it will be tracked while you debug.

Usage

VS Visual Studio

VS has a great rundown of their debugger found here. Instructions about configuration are not specific to Unity and can be ignored, instead Unity has written a how-to guide. If you're looking for video tutorials, this video series is a fantastic overview of using the debugger with Unity. Combining the above resources should give you complete confidence to debug using Visual Studio.

VS Code Visual Studio Code

VSC does not come with a debugger built-in, the Unity extension needs to be manually installed. How-to instructions for debugging can be found here with Debug actions, and Breakpoints being the most relevant information. Instructions about configuration are not specific to Unity and can be ignored.

Rider JetBrains Rider

Rider has detailed information about debugging Unity applications here and here. Rider also has:

Debugging builds

Builds require Development Build and Script Debugging to be enabled in the build settings (FileBuild Settings) to debug script code. When attaching the debugger attach to the built Player and not the Unity Editor. More information can be found here, including the debugging of mobile devices.

  1. JetBrains Rider now prints tracepoints to Unity's Console. Note that you can also view the Unity Console output in Rider.