Greetings friends, today I will present you tools I use everyday as a Unity Developer to debug games and applications during development cycle.
Debugging is a process of identifying and solving software issues which prevent its correct operation. In other words BUG FIXING. What I consider as a bug:
all sorts of exceptions - most common “NullReferenceException”
frame drops due to CPU or GPU overload
There are certain instruments to ease your bug-fight way, the ones I will familiarise you with in this post are:
Unity's console & profiler
Xcode & Instruments
In the start I'll go with total basics, so feel to jump to the section of your interest 🙂
Without further ado, Let's Go!
The engine itself provides some handy instrument to help you run diagnostic. In most cases this will be enough for you to proceed from investigation to fixing phase. Let’s start with the basics.
Unity Developer’s best friend is the console window which resides in the bottom area of the editor. Treat this window as your most valuable tool, don’t you ever dare to close it as it is where you’ll notice any warnings and errors regarding your application runtime.
Console in action.
Double clicking should bring you to the IDE and highlight the line where error occurred. Too easy, right?
I met people who didn’t know about one useful feature of unity’s console window: COLLAPSE!
With that enabled console window will stack all same error logs in one line.
Sometimes diagnosis ends here but not always. There are times where it’s just the beginning of looking where did you loose the data you want to access right now.
This is more advanced tool which is used to detect mostly CPU, GPU or memory related issues - Optimization.
You can add profiler window by going to Window -> Analysis -> Profiler
Here you can see a ton of data that describes your app. The three top ones are the most important, let me elaborate on those.
Displays how much time it took to render a frame as well as details of every tracked task. If all the required assignments need below 16ms to complete, it means your game in that particular second runs on more than 60fps.
Remember that running the game in the unity editor will add some overhead to the execution speed. If it's possible always profile the product on target device.
When looking for a potential frame drop cause one should look for the spikes to appear on the graph. Simply click on it and see the details.
Sample presentation with switch to hierarchy
In my case task that causes frame drop is rendering. It means there could be too many complex objects in the camera view that want to be rendered (draw calls). I cover this in the next section.
You can keep unfolding the hierarchy and go deeper into the call stack. That will lead you to the core of the call stack. The unoptimized code may appear at any depth so keep your eyes wide open!
In some cases you may notice a task named “Gfx.WaitForPresent” on the top of the list. If it happens regularly you should focus on graphics optimization as your project is GPU bound. In other words your CPU is waiting for the Graphics to complete it's tasks.
This tab is all about geometry, it contains information about:
Number of draw calls (total, dynamic batching, static batching and instanced)
Total quantity of triangles and verts used in draw call calculations
When optimizing your game in terms of rendering, developer should focus on lowering the number of draw calls in the first place.
Draw call is a request from an object that wants to be displayed on your screen during a frame. It contains informations about shaders, materials, state in form of CPU work that is passed to GPU.
Remember the golden rule: The lower the better.
The quickest way to lower the draw calls is either:
Reducing the number of mesh objects with material (by combining them, or removing)
Assigning the same material in every place possible and ticking “Enable Instancing” checkbox.
You can read more about graphics optimization here:
Here the details of memory allocation can be seen.
Devs should always be aware of the total operational memory of target devices. When it runs out the game will be terminated due to insufficient resources.
Short on maintaining the memory allocation in unity:
be sure to understand the managed heap PING
know when it is released (eg. Coroutines do not release accumulated memory until the execution is finished)
it gets freed upon destruction of Object (setting object = null does not release the allocated memory)
Find out more:
Unity post about: GENERAL Optimization
Unity post about: MOBILE Optimization
If by any reason you need to access more data within profiler window, you can enable Deep Profiling: PING
Debugging for Mobile
During the past two year period Unity team has put a lot of effort into integrating editor debug experience with mobile devices.
Right now the easiest way is to connect your device with editor either by
ticking Development Build along with Autoconnect Profiler in Build Settings
manually selecting a device from dropdown menu (or entering it’s IP address)
With device connected the debug flow is the same as described above in the built-in tools section.
Now the experience is flawless, but in the past there were many bugs or no features like this at all. That’s why I’ll show you ways to directly connect to your mobile device logs.
Say hello to good old Logcat. This tool comes bundled with Android SDK. It prints out to console system logs. Those can be filtered by adding arguments in the command line.
Assuming you already have downloaded the Android SDK these are the steps to follow to use this tool:
firstly, you’ll need to add ADB to your system file path PING
secondly, make sure to enable USB Debugging PING
Now you’re ready to go.
The command I use in most cases is:
adb logcat -s Unity
The -s argument is associated with filtering all the logs to show only the ones tagged with ‘Unity’. This way you’ll see only logs from your game.
You can find more about logcat and it’s options here: PING
Mac users have access to two essential development tools:
There is much I could say about this software, but to stay short I'll describe it as build&publish environment. When running your game on iOS device a console should appear in the bottom. It is where you can search for any errors or messages.
/Remember these logs point to Xcode project files, not Unity ones!/
Instruments can be used to get some general data of app allocations, CPU and GPU usage, device temperature etc.
When launched one needs to select the first instrument, but there are more to choose from.
Activity Manager will tell you what is the %CPU usage
Allocations feature data about used memory
Metal System Trace gives you an general view into GPU world
To get the data press Record button.
Voila! Looks almost like Unity’s profiler.
How to detect app crashes in production
Mmmm, your app is released. Feels good, eh?
But then you enter google console and see hundred of crashes happening across the whole globe.
Crashlytics come to the rescue! You probably figured it out, these are like Analytics, but analysis is done only regarding crashes.
It not only shows when and where did it happen, but also running OS, device model, LOGS.
With logs in hand you can surely solve the issue in no-time!
One service I could recommend is Fabric PING
That was a brief description of debug tools available for developers. As you can see, there are plenty ways to diagnose your app, hope you enjoyed the text.
Let me know if you’d like to see more in-depth article about optimization in the comment section below. If I can be of any help regarding you project, please contact me 🙂