If you want to get anywhere as a Unity Developer, be it becoming a professional developer or sharing insider apps with friends, you ~have to know how to use the debugger~! No excuses. Read on to learn why and how.
(* = also appealing to all Gentlewomen)
Discuss this article on the Unity Forum
Many scripting issues can be understood more quickly by simply following code execution line by line while inspecting the variables' values along the way. This can be done with the debugger, any time during runtime, before or after entering playmode, in development builds and even to debug editor scripts.
How debugging works
In any Visual Studio project, you will most likely launch your app with the debugger already up and running along with your app. This is called "debug & run".
However Unity Editor is a separate app not connected with Visual Studio. Nor is the app you are developing with Unity runnable from Visual Studio. Instead, you have to "attach" the debugger to the external Unity Editor process.
Thanks to the already installed Visual Studio Tools for Unity (VSTU) plugin you get a button labelled "Attach to Unity" in the VS Toolbar.
By pressing "Attach to Unity" VS will first begin to compile your project and only if there are no errors, it will launch the debugger and attach it to Unity Editor. With the debugger attached, you cannot edit source code anymore as this would affect the state of the app you are debugging.
You can attach the debugger any time with Unity Editor open, whether you are in Playmode or not doesn't matter. Use it at any time you see fit.
For example, if you need to debug code that's unrelated to launching the app you can improve launch and runtime performance of the app by attaching the debugger sometime later, shortly before you need it.
Setting a Breakpoint
A breakpoint tells VS that whenever the marked line of code is executing, it will stop Unity Editor and bring VS in the foreground. Click in that vertical grey bar to the left of the source code of any script to set a breakpoint, shown as big red dot:
The next time this line of code executes while VS is attached to Unity, VS will halt execution and takes over. You can then step code execution line by line and inspect variables. It's as simple as that.
You can open the Locals, Autos, Watch, Call Stack and other debugging windows from the Debug - Windows menu in case they are missing.
Heavily underutilised yet extremely powerful. Imagine you know the code is causing a bug at some point. You don't know when or why. But you do know it can only happen whenever a certain variable has a certain value. In that case:
Set a breakpoint
Right-Click the red breakpoint circle
Enter one or more conditional expressions that would work in the context of the method, for example "count == 9" but even more complex conditions like "myStr.Equals(someOtherStr) && leftLimb.isSwinging == true" are possible!
The breakpoint will now stop only when the entered conditions are met. You can even tell it to break only after the tenth time or execute Actions under certain conditions. I encourage you to experiment with the available options in the Breakpoint Settings dialog.
This should be enough to get you going with conditional breakpoints. Remember this, because it will rarely be needed but it will be a huge timesaver when you do need it!
Stepping through Code
When a breakpoint is hit, you will notice the VS Toolbar icons change.
You now get several options, I'll name the important ones:
Continue (F5) (keep running until the next breakpoint is hit)
Stop (Shift+F5) (detaches the debugger, stops the debug session)
Show Statement (Alt+Num*) (in case you get lost browsing the code)
Step Into (F11) (if the current line has a method with source code available, executes the first line in the first method that VS can step into)
Step Over (F10) (execute the current line and stop at the next line)
Step Out (Shift+F11) (leaves the currently executing method and returns to the next line in the previous method in the call stack)
Try setting a breakpoint and "Step Over" or "Step Into" to see how it works. You'll love it!
With stepping, execution is line by line. After each statement you can further inspect variables to check if the results are as expected.
Tip: It helps debugging a lot by breaking out complex statements into multiple lines. See my previous article GetComponent() only once.
From the Debug - Windows menu you can open either the Locals or Auto windows. These windows show you the variables and objects and their current values from the scope of the current execution marker (the little green arrow).
Rather than logging the variables, you now have them in a window at any time and can see their values when a breakpoint was hit. You can even double-click a value and change it!
Moreover, objects with source code available can be expanded to show their public and internal fields and properties. You can take this as far as needed, inspecting for example entries in an array of lists in a dictionary. Imagine you'd have to do that with Debug.Log(), you would be going crazy!
Sometimes it can be helpful to see variable values that are spread over several classes in one window. This is where the Debug - Windows - Watch windows come in handy.
With a watch window open, simply start typing in the empty entry. Autocompletion will suggest you variables from the current context. You can add as many variables as you need.
Navigating the Callstack
The callstack is similar to what you see in the Debug Console when an exception happens. Only with the debugger you can double-click any entry to navigate how the code execution arrived at the currently executing line.
By jumping up and down the callstack you even get to inspect the variables and their values based on the callstack context. You can follow the code how it got to where it is now.
Logging still has merits
Of course Debug.Log() is still useful. Particularly in places where you need to observe changes over time or when debugging time critical code (where a breakpoint would cause too much delay) logging is a valuable tool. To name just a few examples.
Depending on your level of expertise I recommend:
Debugging for Absolute Beginners
VS Debugger Introduction
If you're using Visual Studio for Mac or use VSCode the above features are still available, although the user interface will be different. Refer to the corresponding manuals for instructions. But the same principes apply.
Once you've used the debugger for something that would have previously taken you hours of pondering and experimenting to fix, you will look at scripting issues quite differently. Your world will never be the same. Your mind will expand beyond imagination. You will wonder how you were ever able to work without it.
Yes, I'm overselling slightly. On the other hand, far too many developers (even professional ones!) neglect, ignore or simply don't know about the debugger. I can only encourage you to try it (more often).