Using Unity’s Debug Inspector

Unity’s debug option for the inspector is one of the small, but hugely important features. Here’s how to find it:

Normal Unity inspector.
Normal Unity inspector.

In the tab dropdown for the inspector chose the Debug option, or Normal to return to defaults.

Unity debug inspector.
Unity debug inspector.

Now the Inspector will show additional information, such as private variables from scripts like this:

Debug inspector showing private fields.
Debug Inspector showing private fields.

 

This is one of the easiest and most comfortable ways to inspect private fields from custom classes. Note, that inspector cannot show everything you might expect it to:

The Debug Inspector does not show properties or static variables.

Just to make sure: The Health field that is shown in the inspector is in fact our private variable health, not the property. Variable names are automatically capitalized and formatted in the inspector.

Quicktip: Use auto-implemented properties, if you don’t need additional code or special names for your backing fields. See this tutorial, if you need to freshen up on how properties work.

Here is the official C# documentation on auto-implemented properties.

Be aware that these “auto-props” will display with a particular name syntax in the debug inspector:

Auto-implemented property in the inspector.
Auto-implemented property in the inspector.

 

The Debug Inspector shows not only private fields on custom scripts, but detailed options for other components.

There are many ways to use the debug option to inspect hidden data or change advanced options on Unity components. Here are a few examples:

Inspector and project browser icons

The debug inspector also works when browsing assets in the project view. If you like, you can assign custom icons to your components. This can help your team to find certain important scripts more easily or if you’re developing your own custom component you might want to give it a branding.

Debug inspector icon field.
Debug inspector icon field.

 

Debug inspector fill in icon for script.
Debug inspector fill in icon for script.

 

Inspector with custom icon on script.
Inspector with custom icon on script.

Advanced animation options

There are several options hidden for animation clips, some of which can come in handy to change, such as the ability to switch to legacy animation, when not using Mecanim. You can also adjust options from this window, instead of switching to the Animation or Animator window (e.g. Sample Rate).

Advanced animation clip options.
Advanced animation clip options.

 

Compare objects by instance id

Sometimes you run into a problem, where an object’s instance ID can help you to debug your scene. (The instance ID is a unique identifier to any object in the scene.) Here is a simplified example to illustrate the use of instance IDs:

Often, you need scripts which persist between scenes, such as GameControllers or AudioManagers. If, for whatever reason, you want your manager class to be a MonoBehaviour that lives on a GameObject in the scene, you will have to make sure that there can only exist one instance of it during runtime (read up on the Singleton Pattern for more).

Usually there are ways to build objects in a way that they are true, problem-free singletons, but sometimes you’re stuck with a solution that is prone to errors:

Instance IDs in the debug inspector.
Instance IDs in the debug inspector.

 

Think of a case, when you have a GameController and due to human error there are multiple instances of it attached to GameObjects in the scene. Instance IDs can give you detailed information about which objects are involved when you run into problems:

Now, if you end up with multiple instances of the GameController, only the first one survives. Additionally, the instance IDs of both objects are printed out, to show you exactly which of the instances in the scene caused the problem.

As stated above, this example is purposely plain. Real-world scenarios, where instance IDs will save your life, are going to be complex and cumbersome to debug without the help of detailed object information.

These were only a few examples of how to make the most of the debug inspector in Unity. Keep your eyes open for hidden options and information that helps your work.

Caching the ‘transform’ and ‘gameObject’ properties

The transform and gameObject properties of MonoBehaviour are often used to check property values against other values.

There are a few reasons to avoid using transform to move objects, but a position-check is a perfectly valid example. There is, however, a small problem with the above code: The transform property internally does a GetComponent() call. This means, that every frame a method call is needed to find the reference to the Transform component of our GameObject.

This code illustrates what is actually going on under the hood of Unity. At this point it is not necessary to fully understand how these internal calls work, just keep in mind that every method call and dot-operation costs performance and therefore we want to avoid them as much as possible.

The solution: Cache your variables and even Unity properties!

Instead of finding a reference to our Transform component in every frame, we do it only once and store it in a variable. You could call this variable myTransform or something, but I prefer to call it the same as the Unity transform property. This way, I don’t have to change any of my working code, when I want to optimize things at the end.

Pay attention to the new keyword, which we use to tell the compiler that we intend to override the inherited member transform from MonoBehaviour. This step is not entirely necessary, but sometimes Unity will throw a warning and remind you that there already exists a variable called transform.

Caching references in variables is a common way to optimize performance.

What we did with the transform property is just one example of caching a reference for later use. We do the same thing whenever we access another script or component, but in case of the built-in Unity properties, I think it is worth mentioning that we can override those with more performant ones.

Note, that this kind of optimization is only effective and noticeable when resources are limited or you are dealing with many script objects. Caching Unity properties for only your player will not speed up your game visibly!