>> I'm Charles and in this video,
I'm going to show you how to use the debugger in
Visual Studio to inspect variables
at one time so you can debug
any issues that arise with your codebase,
even if they don't provide any obvious feedback.
The longer you work on a game,
the larger and more complex it'll become.
In the last video, we learned how to track down
and fix bugs using the debugger in Visual Studio,
a tool that's faster and more reliable than
the traditional approach of adding Debug.Log statements your code.
However, growing projects tend to break in
increasingly random and ambiguous ways.
So you'll need to use
even more sophisticated debugging techniques
to solve your problems.
Take this project, for example, it's relatively small,
yet I've already managed to write some code
that's producing some unexpected behavior and it isn't clear why.
Run the project, we can see that
the player attacks are working as expected.
However, the player dies after a single hit from the enemy,
even at full health.
Not good.
Player death is a mechanic that I created.
So the problem must lie with one of my custom scripts,
specifically the Damageable class,
because it's responsible for tracking damage to the player
and invoking an event when she dies.
We can actually verify this using
the techniques we learned in the last video.
By adding a breakpoint to the method
that invokes the OnDeath event,
we can confirm that, sure enough,
it's being called prematurely when the player gets hit.
Now, at this point, if there was an error in the console,
the solution would be as simple as
tracking it down on the code and fixing it.
But there isn't.
So the next step would be to verify that
the values on my script are correct
and to adjust them if they aren't.
However, that doesn't seem to be the problem either.
The issue must live somewhere in the code.
But how do we determine where without any feedback or clues?
Well, we could enable debug mode on our GameObject,
which will display Damageable's
private member variables in the inspector.
Then we could observe them during Play Mode.
Unfortunately, the variables that we need to watch
are probably local variables that live within
specific methods and even if we could expose them in the editor
or in the console using Debug.Log statements,
it would be too difficult to recreate the problem
and cast the exact values that were causing it.
What are we to do? Well, luckily for us,
Visual Studio provides the perfect solution.
Looking at the Damageable class in Visual Studio,
I've been able to narrow down the issue to this method,
ApplyDamage because it's the one
that's responsible for invoking the on death event.
The problem is that it's invoking the event prematurely
and we need to figure out why.
To that end, let's set up a breakpoint
so we can stop the code's execution
and analyze the state of the class
at the time of the unexpected behavior.
However, the symptoms to this behavior
could occur at any point in this method.
So let's add a breakpoint to the first line.
As a rule of thumb, you want to give yourself
some breathing room when debugging.
If you add a breakpoint on the exact line that's causing the issue,
you may miss some important information.
However, by placing the breakpoint at the start of a method,
we can observe how each variable changes over time
and can get a more complete picture of what's going on.
Let's attach Visual Studio and Unity
and play our game until the breakpoint is triggered.
All right, the Visual Studio debugger
has stopped our code at our first breakpoint,
which is signified by the yellow arrow and highlight.
We can also see that the debugger window has some new information.
These three tabs, labeled Autos, Locals, and Watch,
contain the variables that live in our code
and represent the state of our app,
frozen at this point in time.
We use this window to inspect
variables and determine what's going on.
The Autos tab displays
variables used around the current breakpoint,
meaning it'll update as we step through the code.
The Locals window displays the variables
defined in the local scope,
which is usually the current function or method.
It's currently showing every local variable
that's defined inside of the ApplyDamage method,
even the ones we haven't reached yet.
Finally, the Watch window gives us the ability to create
and evaluate any expression we want.
We can even reference variables that are currently in scope,
which is incredibly powerful.
Finally, if we need a quick and easy way
to determine the value of a variable,
we can simply mouse over it in the code.
In this case, we want to figure out why
the OnDeath method is being invoked prematurely.
Let's step down a few more lines.
As we can see OnDeath is invoked
if the message type variable equals
MessageType.DEAD and mousing over it reveals that it is.
But why?
Well, looking at the line above this one,
it appears that messageType is initialized based on a conditional.
If current hit points is greater than or equal to zero,
set the value to MessageType.DEAD.
Well, that isn't right.
The player should only be considered dead
if their health is less than or equal to zero.
I must have flipped the condition during my most recent refactor.
Let's go ahead and fix this.
There. Now, let's hit "Continue" to restart the execution of code
and switchover to Unity so we can restart the game.
All right, this is what we expect.
Mousing over messageType, we can see that
it's now correctly set to MessageType.DAMAGED.
Let's stop the debugger and switch back to Unity. It works.
Looks like the refactoring I did
caused a game breaking bug that would have been
difficult to track down even in a project as small as mine.
Thankfully, the Visual Studio debugger
allows us to inspect variables so we can analyze
the exact state of our application at any point in time
and truly understand what's going on.
A much better alternative to trying to
expose properties in the inspector
or guessing at what variables are values
may have been causing the problem
and the process is similar across all Visual Studio products.
So whether you're using Visual Studio,
Visual Studio for Mac or Visual Studio Code,
you can take advantage of this powerful tool
so you can debug issues more effectively and fix bugs faster.
[MUSIC]