Debug error log unity

Suggest a change

Suggest a change

Success!

Thank you for helping us improve the quality of Unity Documentation. Although we cannot accept all submissions, we do read each suggested change from our users and will make updates where applicable.

Close

Submission failed

For some reason your suggested change could not be submitted. Please <a>try again</a> in a few minutes. And thank you for taking the time to help us improve the quality of Unity Documentation.

Close

Your name

Your email

Suggestion*

Cancel

Switch to Manual

Declaration

public static void LogError(object message);

Declaration

public static void LogError(object message,
Object context);

Parameters

message String or object to be converted to string representation for display.
context Object to which the message applies.

Description

A variant of Debug.Log that logs an error message to the console.

When you select the message in the console a connection to the context object will be drawn.
This is very useful if you want know on which object an error occurs.

When the message is a string, rich text markup can be used to add emphasis. See the manual page about rich text for details of the different markup tags available.

See Also: Debug.unityLogger, ILogger, Logger.LogError.

using UnityEngine;
using System.Collections;

public class MyGameClass : MonoBehaviour { private Transform transform;

void MyGameMethod() { if (transform == null) Debug.LogError("memberVariable must be set to point to a Transform.", transform); } }

Note that this pauses the editor when ‘ErrorPause’ is enabled.

Suggest a change

Success!

Thank you for helping us improve the quality of Unity Documentation. Although we cannot accept all submissions, we do read each suggested change from our users and will make updates where applicable.

Close

Submission failed

For some reason your suggested change could not be submitted. Please <a>try again</a> in a few minutes. And thank you for taking the time to help us improve the quality of Unity Documentation.

Close

Your name

Your email

Suggestion*

Cancel

Switch to Manual

Declaration

public static void LogError(object message);

Declaration

public static void LogError(object message,
Object context);

Parameters

message String or object to be converted to string representation for display.
context Object to which the message applies.

Description

A variant of Debug.Log that logs an error message to the console.

When you select the message in the console a connection to the context object will be drawn.
This is very useful if you want know on which object an error occurs.

When the message is a string, rich text markup can be used to add emphasis. See the manual page about rich text for details of the different markup tags available.

See Also: Debug.unityLogger, ILogger, Logger.LogError.

using UnityEngine;
using System.Collections;

public class MyGameClass : MonoBehaviour { private Transform transform;

void MyGameMethod() { if (transform == null) Debug.LogError("memberVariable must be set to point to a Transform.", transform); } }

Note that this pauses the editor when ‘ErrorPause’ is enabled.

The most basic thing you can do in programming is print a string onto the console. Unity is the same: You can write a string to Unity Editor’s console, and there are different types of log messages and ways you can customize to make debugging easier.

The most common logging method is the Debug.Log() method which prints a regular string onto the console in Unity in the default text color. There are also 2 other types of log types called Debug.LogWarning() and Debug.LogError() that prints a string in yellow and red, respectively.

Knowing how to use the logging methods and how they interact with the Unity console will make your life much easier. Read more below to learn how to customize debug messages.

Table of Contents

  • Debug.Log
  • Debug.LogWarning
  • Debug.LogError
  • Debug.LogException
  • Format Debug Log Messages with Rich Text Markup
  • Composite Formatting
  • Ending Thoughts

The Debug.Log is the most basic and the easiest way to print a value to the Unity console.

Simply supply it with a string or any value that can be converted into a string and it will display the message on the console.

using System.Collections; using System.Collections.Generic; using UnityEngine; public class TestScript : MonoBehaviour { private void Start() { Debug.Log("This string will be printed to the console."); } }

Code language: C# (cs)

The result will look something like this in the console:

Debug.Log() method

Clicking on the message will bring up a small details section that tells you about where the message comes from.

Console message's details.

For example, the message in the image above is at line number 9 in the script named TestScript.

Additionally, the latest console message will also display at the bottom left corner of Unity Editor.

Additionally, the latest console message will also display at the bottom left corner of Unity Editor.

The Debug.Log method can print the value of anything as long as it can be converted into a string.

using System.Collections; using System.Collections.Generic; using UnityEngine; public class TestScript : MonoBehaviour { private void Start() { float someNumber = 420.69f; bool isVeryCool = true; Debug.Log(someNumber); Debug.Log(someNumber + " BLAZE IT"); Debug.Log(isVeryCool); } }

Code language: C# (cs)

The code above will print 3 lines of messages to the Unity console:

3 lines of console messages.

You can also link a related game object to a console message to make it easier to find where the message comes from by passing an object as the second parameter of the Debug.Log method.

using System.Collections; using System.Collections.Generic; using UnityEngine; public class TestScript : MonoBehaviour { private void Start() { int someNumber = 1234; Debug.Log("This is a number: " + someNumber, transform); } }

Code language: C# (cs)

This will highlight the associated object in the hierarchy window when you click on the message in the console window.

Clicking on a message with an object attached to it in the console will highlight the object in the hierarchy.

Aside from logging messages to the Unity console, Debug.Log (and other logging methods) also logs messages to log files of your game. Information on where to find these log files for each platform can be found here.

Debug.LogWarning

The Debug.LogWarning works the same way as Debug.Log but the message printed will have a warning icon and the color of the message on the bottom left corner of the Unity Editor will be yellow instead.

This one is generally used to give a warning that something might not be working correctly or something is missing from the code but can still work. Something like that. You get the idea.

using System.Collections; using System.Collections.Generic; using UnityEngine; public class TestScript : MonoBehaviour { private void Start() { Debug.LogWarning("Setting the width to more than 300px will result in a drop in performance."); } }

Code language: C# (cs)

This will log a message with a warning icon to the console.

A warning console message.

The warning message shown at the bottom left corner of Unity Editor will be yellow.

A warning message at the bottom left corner of the Unity Editor.

An object can also be passed to the method to link the object with the warning message, just like Debug.Log.

Debug.LogError

The Debug.LogError method behaves in the same way as the Debug.Log method and the Debug.LogWarning method, but the message logged to the Unity console will have an error icon and the message at the bottom of the editor will be red.

This logging method is commonly used for displaying code-breaking error messages to the console.

using System.Collections; using System.Collections.Generic; using UnityEngine; public class TestScript : MonoBehaviour { private void Start() { Debug.LogError("Failed to initialize player's default parameters."); } }

Code language: C# (cs)

The message printed to the console will have an error icon attached to it.

An error icon attached to the console message.

The message shown at the bottom left corner of Unity Editor will have a dark red text color.

Ways To Log And Customize Debug Messages For Unity Console

An object can also be passed to the method to link the object with the error message, just like Debug.Log.

Debug.LogException

The Debug.LogException is used to log exceptions to the Unity console. It works the same way as the regular Debug.LogError except you supply it with an exception object instead of a string.

You use this when you want the error to be more specific, or you want to capture an exception and print it to the console manually.

using System.Collections; using System.Collections.Generic; using UnityEngine; public class TestScript : MonoBehaviour { private void Start() { Debug.LogException( new MissingComponentException( "RigidBody2D is missing in " + transform.gameObject.name + ". RigidBody2D is required for this script to work properly." ), transform ); } }

Code language: C# (cs)

This will log an exception to the console with an error icon.

Debug.LogException's result

This message will display as dark red text at the bottom left corner of the Unity Editor.

Debug.LogException's result at the bottom left corner of the Unity Editor.

It might be a little hard to see as I’m using dark mode, but it’s there.

Format Debug Log Messages with Rich Text Markup

All Debug.Log variants can be further customized using rich text markup. You can do various things such as making a word bold or changing the color of a message.

The rich text markup’s syntax is similar to HTML markup but not entirely the same.

using System.Collections; using System.Collections.Generic; using UnityEngine; public class TestScript : MonoBehaviour { private void Start() { Debug.Log("I do <b>NOT</b> like ducks."); Debug.LogWarning("Something <i>weird</i> might happen. Be careful."); Debug.LogError("This function stopped working <b><i>again</i></b>."); Debug.Log("<color=red>Red</color>/<color=blue>Blue</color>/<color=green>Green</color>"); } }

Code language: C# (cs)

If you’re familiar with HTML, this one should be easy to understand. For more information about the rich text, visit the Unity Rich Text Official Manual page.

Composite Formatting

All Debug.Log variants come with Format versions of themselves which allow more complex formatting called Composite Formatting.

These methods are:

  • Debug.LogFormat
  • Debug.LogWarningFormat
  • Debug.LogErrorFormat

using System.Collections; using System.Collections.Generic; using UnityEngine; public class TestScript : MonoBehaviour { private void Start() { string[] names = { "Chloe", "Angelica", "Yufine", "Tamarinne" }; float[] money = { 1250f, 777f, 240.5723f, 300f }; for (int i = 0; i < names.Length; i++) { Debug.LogFormat("{0} | {1:C2}", names[i], money[i]); } } }

Code language: C# (cs)
Ways To Log And Customize Debug Messages For Unity Console

For more information about composite formatting, refer to MSDN documentation on Composite Formatting.

Ending Thoughts

Knowing how to log messages to the console in different ways can make your debugging process a lot easier, both to yourself and to those who work with you.

I recommend trying those logging methods out yourself in the editor so it’s easier to understand.

I hope this has been a good read for you. Leave a comment if you have suggestions or I’m missing something. And I’ll see you again in the next article!

Cheers!

Attribution

Console icon made by Freepik from www.flaticon.com

Logging is an essential part of a development setup and very useful in production to monitor app health. Unity is a popular cross-device game engine that uses Mono to run scripts written in C#. In this article, we will see how you can enable logging for unhandled exceptions and debug messages in a Unity application. Some of the behavior is the same as for general Mono applications but Unity adds more steps to the lifecycle of the application that needs to be taken into account. In the end we also look at how we can use this to log from a Unity application to elmah.io.

Logging in Unity

Existing logging solutions

The easiest method for logging in a local setting is definitely just to use the Unity IDE where you will then see any logs or exceptions in the console window. You can also build a version of your application that prints the console output directly in the app. These options are nice but not always possible or practical. If it is not possible to attach the debugger to the place that you run the application then you can’t use the Unity IDE to log errors. Then our other option is to add the in-app console log but this can fill much of the interface and you might not want the user to see your error log. Another problem is that we also want to do more than just see the errors separately. We want to collect the errors in our logging system.

Unity already has a system for cloud logging called Cloud Diagnostics. This is well-integrated into the Unity platform. But we would probably rather have the errors be logged to our existing error logging service instead of adding another platform to monitor our applications.

Application Lifecycle

Mono itself has the same entry point as the applications that we can create in .NET.

public class HelloWorld
{
    // Method is called when application is started.
    public static void Main(string[] args)
    {
        // Setup logging here.
    }
}

But Unity is a component-based framework and does not make it possible to create a Main function.

Instead, we need to add an empty component to the scene that we work with. It is a good idea to have the logging in a separate component so that you know that the component is alive throughout the whole lifetime of the application.

Create Empty

Then we can add a script to the component where we will set up logging.

Set up logging component

In this, we can add the following methods that will get called during different lifecycle events in the component.

using UnityEngine;

public class Logging : MonoBehaviour
{
    // This function is always called before any Start functions
    void Awake()
    {
        
    }

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    // This function is called after all frame updates for the last frame of the object’s existence
    void OnDestroy()
    {
        
    }
}

The important thing to note is that Awake is called before any Start function is called. So we will want to add the logging to the application in the Awake function. Doing this means that we can catch any error that is thrown in Start or Update where most of the workload is normally done. We can’t make any promises for what order Awake functions in different components are called, so it is generally a good idea to delay code that could throw errors from Awake until Start if possible.

Standard error handling in Unity

The code that you run in the Start and Update functions can tell the program that something went wrong in multiple ways. If the error is not critical to the further execution of the program then you can log an error with

Debug.LogError("Something went wrong");
Debug.LogWarning("Something went wrong");
Debug.LogException(new Exception("Something went wrong"));

If the execution is critical or if you want to enable the caller to handle exceptions through the call stack then you can throw an exception instead.

throw new Exception("Something really went wrong");

Often you don’t go around and create a lot of the logic yourself when developing Unity apps. But instead, use some implementation from the standard libraries. These standard libraries are a mix of wrappers for C++ libraries and natively developed .NET packages. There is not a universal rule for when a library uses either logging method so we will have to handle both scenarios.

Event Handler for Debug logs

We can subscribe to an event that is triggered every time something is logged with Debug like so.

void Awake()
{
    Application.logMessageReceivedThreaded += Application_logMessageReceivedThreaded;
}

private void Application_logMessageReceivedThreaded(string condition, string stackTrace, LogType type)
{
    // Log log to your logging system.
}

Then we can handle every time something logs an error of one of the following types (severities): Assert, Error, Exception, Log, Warning. We could even filter on this if we e.g only want to log Assert or Exception errors. This can be useful as the same error can occur in the body of the Update function every time it is called which can quickly run into the thousands when it is called every frame.

Event Handler for Unhandled Exceptions

We can also subscribe to the event of an unhandled error occurring. This can also be done in the Awake function.

void Awake()
{
    TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
}

private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
    // Log `e.Exception` to you logging system
}

We can get much more detail about the exception and the context that it occurred in when we have an Exception object. It looks like Unity catches all Exceptions that are thrown in non-async threads. So these will be handled by the Debug logger, but all Exceptions that are thrown in a Task will instead be caught by the UnobservedTaskException event handler.

Unsubscribing events

It is a good idea to also unsubscribe to events once the application closes but not strictly necessary as the application is about to close anyway. We do this in the counterpart to the Awake function in the lifecycle which is OnDestroy.

// This function is called after all frame updates for the last frame of the object’s existence
void OnDestroy()
{
    Application.logMessageReceivedThreaded -= Application_logMessageReceivedThreaded;
    TaskScheduler.UnobservedTaskException -= TaskScheduler_UnobservedTaskException;
}

Logging to elmah.io from Unity

We have the capability to get all relevant information about logs and exceptions. So now, we just have to log it to our cloud logging service of choice. Not to be biased but for me, that’s elmah.io. So let’s see how we can do that. The following will use the newest preview version of the Elmah.Io.Client package.

You can’t add packages from Nuget to a Unity project directly but you can download the dll files and add them manually. So I simply went to
https://nuget.org/packages/Elmah.Io.Client selected the newest preview version and clicked Download package.
This gives us a .nupkg file that we can simply rename to .zip and open using the file explorer. In this, we will see a lib folder that contains all the versions that this package targets. We need the netstandard2.0 version as Unity is compatible with this version. So we just copy the files in that folder and paste them into a new folder Libraries in the Assets folder of our Unity project. Elmah.Io.Client almost only uses the standard libraries but still has a single dependency on Newtonsoft.Json. So we just need to do the same for the Newtonsoft.Json package and add its dll’s to the Libraries folder. When dll’s are placed within the Assets folder then Unity will automatically add them during the build process.

Now that we have the package installed then we can begin to log messages.

We first add an IElmahIoAPI property to the component so that we don’t need to instantiate a new every time we log.

private IElmahioAPI api;

Then we can start by logging Debug logs

private void Application_logMessageReceivedThreaded(string condition, string stackTrace, LogType type)
{
    if (api == null)
    {
        api = ElmahioAPI.Create("API_KEY");
    }

    Severity severity = Severity.Debug;
    switch (type)
    {
        case LogType.Assert:
            severity = Severity.Information;
            break;
        case LogType.Error:
            severity = Severity.Error;
            break;
        case LogType.Exception:
            severity = Severity.Error;
            break;
        case LogType.Log:
            severity = Severity.Verbose;
            break;
        case LogType.Warning:
            severity = Severity.Warning;
            break;
    }

    var message = new CreateMessage()
    {
        Title = condition,
        Detail = stackTrace,
        Severity = severity.ToString(),
        Url = Application.absoluteURL
    };

    api.Messages.Create("log-id", message);
}

We don’t really have a lot of information when logging from Debug but we do have a log type that is somewhat equivalent to our log severity, so we switch on the log types and assign each a severity. This is only an attempt at mapping but it still gives a lot of information.

Next, we also want to log unhandled exceptions and we do this like like the following which is very close to how we would log Exceptions manually in other frameworks:

private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
    if (api == null)
    {
        api = ElmahioAPI.Create("API_KEY");
    }

    var exception = e.Exception;
    var baseException = exception?.GetBaseException();

    var message = new CreateMessage()
    {
        Data = exception?.ToDataList(),
        DateTime = DateTime.UtcNow,
        Detail = exception?.ToString(),
        Severity = "Error",
        Source = baseException?.Source,
        Title = baseException?.Message ?? "Unhandled Unity exception",
        Type = baseException?.GetType().FullName,
    };

    api.Messages.Create("log-id", message);
}

Testing the integration

Now let’s provoke one of the most common errors Object reference not set to an instance of an object which we have also blogged about before Debugging System.NullReferenceException — Object reference not set to an instance of an object

We provoke the Exception with the following in our Start function.

private List<string> list { get; set; }

// Start is called before the first frame update
void Start()
{
    list.Add("Hello");
}

There will be thrown an Exception when we try to add "Hello" to the list as the list is not initialized yet.
This Exception is not thrown in an asynchronous thread so the Debug logger will observe it and we will log the error through the logMessageReceivedThreaded event handler.

This example can be found at https://github.com/elmahio-blog/Elmah.Io.UnityExample.

If we instead change the Start function to be asynchronous in a Task then we would see it be handled by the UnobservedTaskException event handler

private List<string> list { get; set; }

// Start is called before the first frame update
async Task Start()
{
    list.Add("Hello");
}

So now we have successfully added logging to elmah.io from a Unity application and seen that it works.

Conclusion

In this article, we have looked at existing Unity logging solutions. Then we have seen how we can log errors for the full life time of an application in general. In the end, we looked at how we can use this to log Exceptions and Debug Messages to elmah.io.

elmah.io: Error logging and Uptime Monitoring for your web apps

This blog post is brought to you by elmah.io. elmah.io is error logging, uptime monitoring, deployment tracking, and service heartbeats for your .NET and JavaScript applications. Stop relying on your users to notify you when something is wrong or dig through hundreds of megabytes of log files spread across servers. With elmah.io, we store all of your log messages, notify you through popular channels like email, Slack, and Microsoft Teams, and help you fix errors fast.

elmah.io app banner

See how we can help you monitor your website for crashes
Monitor your website

Объявление

public static void Log(object message);

public static void Log(object message,
Object context);

Параметры

message Строка или объект, который нужно преобразовать в строковое представление для отображения.
context Объект, к которому относится сообщение.

Описание

Записывает сообщение в консоль Unity.

Используйте Debug.Log для печати информационных сообщений, помогающих отлаживать приложение. Например, вы можете напечатать сообщение, содержащее GameObject.name и информацию о текущем состоянии объекта.

Вы можете форматировать сообщения с помощью объединения строк:
Debug.Log("Text: " + myText.text);

Вы также можете использовать разметку Rich Text.

Если вы передаете GameObject или Component в качестве дополнительного контекста аргумент, Unity мгновенно выделяет этот объект в окне Иерархия, когда вы щелкаете сообщение журнала в Консоли. Используйте объект context, когда у вас есть много экземпляров объекта в сцене, чтобы вы могли определить, какой из них создал сообщение. Пример 2 ниже иллюстрирует, как работает эта функция. При запуске этого примера сначала щелкните один из
кубы, которые он создает в сцене. В этом примере сообщение журнала печатается в Console. Когда вы нажимаете на сообщение, Unity выделяет объект context в окне Hierarchy — в данном случае куб, на который вы нажали в сцене.

Пример 1. Покажите некоторые примеры использования Debug.Log:

using UnityEngine;
using System.Collections;

public class MyGameClass : MonoBehaviour
{
// A Light used in the Scene and needed by MyGameMethod().
public Light light;

void MyGameMethod()
{
// Message with a GameObject name.
Debug.Log("Hello: " + gameObject.name);

// Message with light type. This is an Object example.
Debug.Log(light.type);

// Message using rich text.
Debug.Log("Error: AssetBundle not found");
}
}

Пример 2. Показать выделение нажатого GameObject:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// Debug.Log example
//
// Create three cubes. Place them around the world origin.
// If a cube is clicked use Debug.Log to announce it. Use
// Debug.Log with two arguments. Argument two allows the
// cube to be automatically selected in the hierarchy when
// the console message is clicked.
//
// Add this script to an empty GameObject.

public class Example : MonoBehaviour
{
private GameObject[] cubes;

void Awake()
{
// Create three cubes and place them close to the world space center.
cubes = new GameObject[3];
float f = 25.0f;
float p = -2.0f;
float[] z = new float[] {0.5f, 0.0f, 0.5f};

for (int i = 0; i < 3; i++)
{
// Position and rotate each cube.
cubes[i] = GameObject.CreatePrimitive(PrimitiveType.Cube);
cubes[i].name = "Cube" + (i + 1).ToString();
cubes[i].transform.Rotate(0.0f, f, 0.0f);
cubes[i].transform.position = new Vector3(p, 0.0f, z[i]);
f -= 25.0f;
p = p + 2.0f;
}

// Position and rotate the camera to view all three cubes.
Camera.main.transform.position = new Vector3(3.0f, 1.5f, 3.0f);
Camera.main.transform.localEulerAngles = new Vector3(25.0f, -140.0f, 0.0f);
}

void Update()
{
// Process a mouse button click.
if (Input.GetMouseButtonDown(0))
{
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;

if (Physics.Raycast(ray, out hit))
{
// Visit each cube and determine if it has been clicked.
for (int i = 0; i < 3; i++)
{
if (hit.collider.gameObject == cubes[i])
{
// This cube was clicked.
Debug.Log("Hit " + cubes[i].name, cubes[i]);
}
}
}
}
}
}

Обратите внимание, что Unity также добавляет сообщения Debug.Log в файлы журнала редактора и проигрывателя. Дополнительные сведения о доступе к этим файлам на разных платформах см. в разделе Файлы журнала.

So you want to build a game using the Unity engine? You’ve sat down and designed the game that you’d like to create, put together a little project management board, and you’ve started implementing the logic needed to drive your game.

You’ve hit the Play button a few times and tested a few of the scripts that you’ve created for the base functionality and now that you’re working on something a little more complex, you’ve hit Play and your IDE (Integrated Development Environment) hasn’t thrown any errors your way.

My Code Works But How Gandalf Meme

Everything looks good and the game runs, but something isn’t quite right. You’re not getting the data that you’re expecting to get or you’re just not getting the results that you need. This can be super frustrating as a Unity beginner, but this article will help you get through the process of debugging your Unity project using the Debug.Log statement.

We’ll be running through the different ways that you can use the Debug.Log statement, formatting the output to be more readable and looking at a few ways to ensure that you’re using the Debug.Log statement effectively.

For this article, I’ll be assuming that you’re familiar with the Unity engine interface and have already written your first script. We’ll be creating a very simple project with which to demonstrate the use of the statements, but I’ll be adding screenshots and an explanation of the process as we go along.

  • Setting up the base project
  • How to use the Debug.Log statement in Unity
    • Using the Debug.Log statement to determine the name of a game object
    • Using the Debug.Log statement to determine the value of a conditional
    • Using the Debug.Log statement to determine when a function is being called
  • Other types of debug messages

Setting up the base project

For this article, I’ll be creating a 3D project in Unity 2021.3.4f1, but the version of the Unity engine that you use will not matter. I’ll also be using VS Community 2019, so you may notice a few interface differences if you’re using VS Code or the Rider IDE, but the principles demonstrated here will be applicable to any IDE.

In the scene below, I’ve got a plane and a few primitive objects. Each of these objects has a unique name (their primitive type), transform, and script. They will be numbered 1 (Sphere), 2 (Cube), 3 (Capsule), and 4 (Cylinder), respectively.

Objects With Names

Next, I created a folder for my scripts, a GameManager script and a GameManager game object within the Hierarchy which will contain the GameManager script that I’ve just created.

GameManager Script Object

I then dragged or assigned the GameManager.cs script to the game object that I created in the Hierarchy, which will run when we hit the play button. Now that we’re all set up, we can look at the basic usage of the Debug.Log statement.

Script to Game Object

How to use the Debug.Log statement in Unity

Now that we have our GameManager script assigned to the GameManager game object within our Test Scene, we can insert our first Debug.Log statement to test that it runs when we need it to.

The syntax for the Debug.Log statement is as seen in the screen to the right. Here I’ve simply stated “Debug.Log(”Hello!);” and since I’ve inserted this statement into our Start method, this should run once when we run our game:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameManager : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        Debug.Log("Hello!");
    }

    // Update is called once per frame
    void Update()
    {

    }
}

If we go ahead and hit the Play button in the Unity Editor, you’ll see word “Hello!” printed in the Editor Console window.

Hello World Unity Editor

We are now able to output simple text to the console using the Debug.Log statement, but it’s still not really that valuable to us when debugging. So let’s try displaying the value of a certain variable that we’ve created when we start up our game.

To do this, I’ve created a private integer called testValue (as seen below) within our GameManager.cs script and I’ve assigned a value to it within the Start function. You may also note that I am able to create a more complex Debug.Log statement by combining the text and the testValue and separating it with a + sign. You’ll also notice that I’ve added a space character between the last character of the simple text and the variable to create some space in the Console window:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameManager : MonoBehaviour
{
    private int testValue;

    // Start is called before the first frame update
    void Start()
    {
        testValue = 1000;
        Debug.Log("This is the value of testValue: " + testValue);
    }

    // Update is called once per frame
    void Update()
    {

    }
}

Let’s save our script and head back to the Unity editor to see what the output in the console will be.

TestValue 1000

Great! We can now see the assigned value of testValue, as well as the little bit of text we’ve added for us to better understand the output in the Console window.

Using the Debug.Log statement to determine the name of a game object

Let’s create a reference to a game object within our script, attach it to the script within the Unity Editor, and then use the Debug.Log statement to output the name of that object:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameManager : MonoBehaviour
{
    public GameObject testObject;

    void Awake()
    {
        Debug.Log(testObject.name);
    }
}

Once you’ve attached the object to the game object field on the GameManager.cs script, within the Unity Editor, you’ll be able to hit Play and the name of the game object that’s being referenced will be shown in the editor.

Name of Object Shown

Using the Debug.Log statement to determine the value of a conditional

We could also use the Debug.Log statement to determine the value of a conditional or a Boolean. Let’s create two integer values and then check whether or not they are the same. To do this, I’ve declared and initialized two integers (a and b) and used a Debug.Log statement to check if they are equal:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameManager : MonoBehaviour
{
    private int a = 51;
    private int b = 62;

    void Awake()
    {
        Debug.Log(a == b);
    }
}

Since the a is not the same as b, the output of the console is as expected.

False Message

Using the Debug.Log statement to determine when a function is being called

In the previous section, we learned about the syntax for a simple Debug.Log statement and added a variable value to the statement. We were also able to see the output to the console. In this section, I’ll be looking at the timing of certain Unity functions and how to tell when a custom function has been called.

The following is taken from the official Unity documentation on the order of execution for event functions.

Unity script functions will execute in a defined order when your script is run and it can be really valuable to see when a specific event or function is triggered, when debugging. Let’s have a look at the following flow diagram, provided by Unity.

From the diagram below, we can see that the Awake function is the first function to be called when a Unity script is run. We then have the OnEnable and Start methods running sequentially.

Diagram Showing Functions

Let’s test this order with a simple script and the insertion of a few Debug.Log statements. I’ve added a testValue integer and then customized each Debug.Log statement so that we know where each of them is being run. The statement above each Debug.Log statement simply increments the value of testValue:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameManager : MonoBehaviour
{
    private int testValue = 0;

    private void Awake()
    {
        testValue++;
        Debug.Log("This was run in the Awake method: " + testValue);
    }

    private void OnEnable()
    {
        testValue++;
        Debug.Log("This was run in the OnEnable method: " + testValue);
    }

    private void Start()
    {
        testValue++;
        Debug.Log("This was run in the Start method: " + testValue);
    }
}

Let’s see what happens in the Console window when we hit the Play button.

Great! We can see that the Awake method executes first, the OnEnable method next and then the Start method. We can also see that each of these methods only runs once when we hit the Play button.

Three Messages

Now let’s create a custom function called OurOwnFunction, which will contain a Debug.Log statement of its own. We’ll call this function in two of the other Unity functions and see what the output is:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameManager : MonoBehaviour
{
    private int testValue = 0;

    private void Awake()
    {
        testValue++;
        Debug.Log("This was run in the Awake method: " + testValue);
        OurOwnFunction();
    }

    private void OnEnable()
    {
        testValue++;
        Debug.Log("This was run in the OnEnable method: " + testValue);
    }

    private void Start()
    {
        testValue++;
        Debug.Log("This was run in the Start method: " + testValue);
        OurOwnFunction();
    }

    private void OurOwnFunction()
    {
        Debug.Log("This is the custom function call!");
    }
}

The output in the Console is shown below and we can now see that our custom function is called in the Awake and Start functions, respectively.

Five Messages

Other types of debug messages

Now, we’ve looked at ways in which we can use the Debug.Log statement, but there are also other categories of debug statements that we could use. These statements are used in the same way that the Debug.Log statement is used but allow us to display warnings or errors in the Unity Console:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameManager : MonoBehaviour
{
    void Start()
    {
        Debug.Log("This is a normal log.");
        Debug.LogWarning("This is a warning message.");
        Debug.LogError("This is an error message.");
    }
}

And here we have the output of the above.

Output Messages

In conclusion

Using the Debug statement can be very helpful in seeing what the value of certain variables or objects are at runtime, determining whether or not a function is actually running how and when you mean it to or even just tracking down a pesky bug.

I hope that you have found this useful and are able to use Debug statements more effectively within your project. Just remember to remove them or turn them into comments when they’re no longer in use and you’re all set to debug your way out of your next big game.

LogRocket: Full visibility into your web and mobile apps

LogRocket Dashboard Free Trial Banner

LogRocket is a frontend application monitoring solution that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.

In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page and mobile apps.

Try it for free.

Debugging in Unity can be a very simple thing to do.

In fact, even if you’re still new to Unity, you’ve probably already used Debug Log to send basic messages to the Console.

Which is useful, as being able to trigger messages from your scripts can be a great way to understand what’s happening behind the scenes.

However…

While using Debug Log to display a single message in the Console can be very straightforward, knowing how to use Unity’s debugging tools to manage an entire project can be much more challenging.

For example, how can you tell the difference between good log messages, that confirm that things are working properly, from bad ones, that can tell you that something’s gone wrong?

How can you manage different categories of debug messages, and avoid cluttering your Console with information about old work that you’ve already finished?

And when your game is done, how can you easily turn off some or all of your debug messages, to prevent them from negatively impacting your game’s performance?

There’s a lot to consider, but don’t worry, because in this article you’ll learn the basics of debugging in Unity, how you can use Unity’s debugging tools to your advantage and how to easily manage your debug messages as you go.

Here’s what you’ll find on this page:

  • How to use Debug Log in Unity
  • How to format Debug Log messages in Unity
  • The best way to use Debug Log
  • How to disable Debug Log messages in Unity

Let’s get started.

The simplest way to print a message in the console in Unity is by using the Debug Log function, which takes a string value and displays it in the Console window.

Like this:

void Start()
    {
        Debug.Log("Hello World");
    }

Which, in the Console, looks like this:

Example of Debug Log in Unity

In its most basic form, Debug Log prints a single message, that will be shown in the Console when that line of code gets executed.

However, while what you see in the Console is a simple string, you can pass in just about anything you like.

For example, a float value:

float health = 100;
void Start()
{
    Debug.Log(health);
}

Which can be useful for checking the value of a variable at a specific time.

Like this:

Debug a float variable in Unity

An object or property reference:

void Start()
{
    Debug.Log(gameObject.name);
}

Which, in this case, gets the name of the object that the script is attached to.

Which, in the Console, looks like this:

Debug Game Object example Unity

A conditional value:

void Start()
{
    Debug.Log(1 + 1 == 2);
}

Which, in the Console, returns a true or false statement depending on the result of the conditional check.

Like this:

Debug Boolean condition example in Unity

Or a mixture of text and variables:

float health = 100;
void Start()
{
    Debug.Log("Player Health: " + health);
}

Which allows you to add any combination of text and variable data to a Console message.

And looks like this:

Debug Log string and variables example

How to connect a Debug Log message with a specific object

While the basic method of using Debug Log displays a message in the Console, it’s also possible to provide a reference to an Object that the message may relate to.

For example, you could pass in a reference to the game object that the script is attached to.

Like this:

float health = 100;
void Start()
{
    // Logs the player's health, with a reference to this game object.
    Debug.Log("Player Health: " + health, gameObject);
}

Then, in the Unity Editor, clicking on the message in the Console will show you exactly which object it relates to.

Like this:

Debug Log Context

Providing an object reference will show you, in the Editor, which object relates to a specific Console message.

This can be useful for working out which object is associated with a specific message or error, particularly if it could have been generated from any one of a number of duplicated objects.

Debug Log vs Print to Console

Print is a built-in method that prints a message to the Console in Unity in almost the exact same way as Debug Log does.

Like this:

print("This is a print message");

The only real difference is that print is a little easier to write however it doesn’t support an object context in the same way as Debug Log does.

Print is also a method of the Monobehaviour Class meaning that, if your script doesn’t inherit from Monobehaviour, for example, because it’s static, then you won’t be able to use Print, and you’ll need to use Debug Log instead.

How to use Debug Warning and Debug Error

While Debug Log can be useful for displaying information about what’s happening in your game, it’s also possible to use the Debug Console to display your own warnings and errors as well.

This works by using the Log Warning and Log Error functions.

Like this:

void Start()
    {
        Debug.Log("This is a basic log message");
        Debug.LogWarning("This is a basic warning message");
        Debug.LogError("This is a basic error message");
    }

Which, in the Console, will appear as errors and warnings, just like the ones that are generated by Unity.

Like this:

Console Log Messages in Unity

Debug Log, Warning and Error will each display a message of that category in the Console.

This can be useful for raising different types of notification, instead of just basic messages, and can be particularly helpful when you want to distinguish between informational logs and an alert that something is not working in the way that it’s supposed to.

For example, you could use a warning to remind yourself that a particular script hasn’t been set up properly, or an error to catch a mistake that you know will cause a problem.

Log Messages, Warnings and Errors can each be shown or hidden by using the filtering tools available in the top right-hand corner of the Console.

Filter notifications in Debug Console Unity

You can use the filter buttons in the Console to hide certain types of log messages. Be careful though, it can be very easy to forget that certain messages are being hidden.

Using different categories of messages can help you to find problems in your game more easily.

But, that can sometimes be difficult to do when you’re not sure when an error has occurred and what else was happening at the time.

So how can you debug your game in a way that makes catching problems easier to do.

How to use debug messages to check for problems

One basic method of catching issues as they happen is to enable Error Pause in the Console.

Error Pause in Unity

Enabling Error Pause will stop the game when something goes wrong.

This will pause the Unity Editor when an error occurs which can make it significantly easier to work out what the cause was.

However, that’s not the only way you can pause the Editor using debug messages.

Debug Break, for example, allows you to deliberately pause the Unity Editor at a specific moment in time:

Debug.Break();

This can be useful for diagnosing problems or checking data that would be difficult to see while the game runs at full speed.

Lastly, Debug Assert can be used to double-check if what you expected to happen in a script actually did.

This works by passing in a conditional value to the Assert function, that will either be true or false, along with a message, that can be used to describe the problem.

For example:

public int one = 1;
public int two = 2;
public int three = 3;
void Start()
{
    Debug.Assert(one + two == three, "1 plus 2 did not equal 3");
}

The Debug Assert function expects the conditional value to be true and, if it’s not, an error will be raised, using the message that’s passed in.

This can be useful for double-checking what you think you know, or testing to see if variable data is what you thought it was going to be.

By default, Debug Assert assumes that the conditional value that you pass in is meant to be true.

However, there may be times when you want to check that something is false, that two things are not the same or that two float-based values, which can be difficult to directly compare, are roughly equal or not.

Luckily, the Assert Class provides a number of additional comparison functions that allows you to do exactly that and to check that a value or a method is doing what it’s meant to do.

Visual debugging in Unity

While Debug Log can be useful for understanding what’s happing to the data in your scripts, it can sometimes be easier to see what’s going on behind the scenes.

In Unity, there are a few different ways to do this.

For example, the Inspector has a debug mode, that allows you to see normally hidden information about a component, such as the values of private variables.

Debug Inspector example in Unity

Enabling the Debug Inspector will show you additional information about an object’s components, including the values of private variables.

The Debug Class also provides two methods for displaying visual lines in the Unity Editor as the game runs, which can be useful for visually identifying direction vectors and even connections between objects. 

Debug Draw Line, for example, draws a line between two points, such as two object positions, and can be useful for showing a link between objects in the Scene.

Like this:

public class VisualDebugging : MonoBehaviour
{
    public Transform otherCube;
    void Update()
    {
        // Draws a line between the object and the other cube
        Debug.DrawLine(transform.position, otherCube.transform.position);
    }
}

While Debug Draw Ray, allows you to draw a direction vector in the scene, which can help to debug detection zones, weapon trajectories and mouse to world input:

Like this:

public class VisualDebugging : MonoBehaviour
{
    void Update()
    {
        // Draws a 10 unit long line in the Scene view going up
        Debug.DrawRay(transform.position, Vector3.up * 10);
    }
}

How to format Debug Log messages in Unity

Once you’re familiar with how to print a message to the Console in Unity, you might want to format how that message is displayed.

The dotted menu icon at the top right of the Console, allows you to hide some of the additional information that you may not always need but that is provided by default.

It also allows you to change the number of lines used to display each entry.

Console Formatting Options in Unity

Which can make reading the Console much easier to do at a glance:

Debug Console - 1 line per entry

But that’s not all.

While Unity provides a number of filtering and display options in the Console window, it’s possible to format the actual text that is displayed in the message, using Rich Text Formatting.

Which can be used to change the size, emphasis and even the colour of text in the Debug Console window.

How to change the colour of Debug Log messages in the Console

To change the colour of the text in a Debug Log message, simply wrap the text you’d like to highlight with a Color Tag.

Like this:

Debug.Log("<color=red>This is a red message</color>");
Debug.Log("<color=blue>This is a blue message</color>");
Debug.Log("This is <color=red>red</color> & <color=blue>blue</color>");
Debug.Log("<color=#cd542a>This is my favourite shade of orange</color>");

The Color Tag accepts colours defined by specific names, such as red, blue or magenta as well as hex values.

It’s also possible to make the text in a Debug Log message bold, italic or even change its size.

How to make Debug Log text bold, italic or create new lines

To change the formatting of the Debug Console text, simply add tags before and after whatever text you’d like to format.

Like this:

Debug.Log("<b>This is bold.</b>");
Debug.Log("<i>This is italic</i>");
Debug.Log("<size=25>This Text is BIG</size>");
Debug.Log("<size=5>This Text isn't</size>");

It’s even possible to create new lines using the new line character. 

Like this:

Debug.Log("This is a n new line.");

For more information on how to format Console messages in Unity, see the official documentation here.

How to use Debug Log Format

Debug Log, Debug Warning and Debug Error each allow you to send a message to the Console.

And, by using string concatenation, which typically involves adding variables and sections of text together to form a single string, it’s possible to record information to the Console in pretty much any way that you would like.

However, combining multiple parameters and sections of text in this way can lead to lines of code that are long and tricky to write.

Instead, formatting a string with defined parameters can be an easier way to insert data into the text without splitting it up.

To use string formatting with debug messages in Unity, simply choose the Format version of the Log, Warning or Error functions: Log Format, Warning Format or Error Format, which will allow you to insert parameters into the string of the message without breaking it up.

Like this:

string playerName = "Keith";
float health = 100;
void Start()
{
    Debug.LogFormat("{0}'s Health is {1}", playerName, health);
}

This works by marking a numbered position in your text with brackets for each of the arguments that you pass in to the Format method.

In this case, the player’s name is the first argument, marked with a 0, while their health value is the second, marked with a 1.

Which, in the Console, looks like this:

Debug Log Format example in Unity

Log Format also makes it possible to display data in a specific format.

This can be useful when numbers, for example, need to be displayed to a specific number of digits. Such as for a timer that shows a minutes and seconds display. 

Like this:

void WhatsTheTime()
{
    float minutes = Mathf.FloorToInt(Time.realtimeSinceStartup / 60);
    float seconds = Mathf.FloorToInt(Time.realtimeSinceStartup % 60);
    Debug.LogFormat("The game has been running for {0:00}:{1:00}", minutes, seconds);
}

In this case, each of the placeholders also specifies that the number passed in should be displayed as a 2 digit value.

The best way to use Debug Log

Debug Log is an extremely useful feature of Unity that allows you to understand what’s happening behind the scenes of your game in an easy and simple way.

However…

While the Debug Log function might appear to be simple and lightweight, it can actually be very slow and, depending on how you’re using Debug Log in your game, can cause significant performance issues.

This happens because Debug Log writes every message to an actual file, on your computer’s hard disk, which can be a slow operation to perform.

What’s more, the Debug Log function creates garbage which, if used frequently or excessively, can lead to stuttering and hitches in gameplay as it’s collected.

While this isn’t necessarily a problem when you’re working on your game, it might surprise you to know that debug messages will be included, and called, in your finished build by default.

Meaning that every Debug Log, Warning and Error function that you use while you’re building your game will be also be called, and logged, in your finished game too.

In some cases, this might be exactly what you want. 

After all, the purpose of logging information is so that you can use it to identify problems.

However, if you’re using Debug Log excessively in your project, it can cause a noticeable drop in performance.

For this reason, it can be a good idea to use Debug Log sparingly and to avoid calling it frequently in Update.

However, depending on how much you’ve used Debug Log, you might want to completely disable log messages in your finished game.

So how can you turn Debug Log off? 

How to disable Debug Log messages in Unity

Because of the potential performance impact of using Debug Log in your game, you may wish to turn off some or all debugging in your finished project.

There are a number of ways you could do this.

For example, it’s possible to exclude certain code from being used in built games with Platform Dependent Compilation.

Like this:

#if UNITY_EDITOR
     Debug.Log("This will only be included in the Editor");
 #endif

This will mean that code inside of the conditional statement simply won’t be compiled if the platform doesn’t match, which can be useful for running platform-specific debugging or for turning it off altogether.

However,

While checking if the game is running in the Editor or in a standalone build will work, it’s not a convenient option and, if you’re using multiple Debug Log messages throughout your code, wrapping each one with a conditional statement can be time-consuming and can clutter up your scripts.

So what are the alternatives?

How can you turn off some or all of the debugging in your game, without adding conditional checks to every Debug Log call in every script?

Option 1: Disable the Player Log

In Project Settings, under the Player Tab, you’ll find an option to disable the Player Log, which is the file that Debug Log writes to when it’s called.

Use Player Log Option

Disabling the Player Log prevents Unity from writing a log file when the game runs. However this won’t stop Debug Log from being called.

This can dramatically improve performance as, writing to a file, compared to most game functions, can be an extremely slow process.

However, while this will improve performance dramatically, by removing the need to write each log entry to disk, Debug Log will still be called and, as a result, will still generate garbage, which can cause performance issues.

If you’re only occasionally calling Debug Log, this might not be a problem for you.

But, if you’re using Debug Log frequently, from many different objects, you may start to notice stuttering and hitches as garbage is collected.

In which case, turning off the Player Log doesn’t make a lot of sense, as you’d still be sacrificing part of your game’s performance with no real benefit.

So what else can you do?

Option 2: Use a custom Debug function

One option for disabling log messages in your finished project is to create a custom debug function inside a static class and then wrap that in a conditional check.

Like this:

public static class GameLog
{
    public static void LogMessage(string message)
    {
        #if UNITY_EDITOR
        Debug.Log(message);
        #endif
    }
    public static void LogWarning(string message)
    {
        #if UNITY_EDITOR
        Debug.LogWarning(message);
        #endif
    }
    public static void LogError(string message)
    {
        #if UNITY_EDITOR
        Debug.LogWarning(message);
        #endif
    }
}

Then whenever you want to use Debug Log, simply call your custom function instead of the standard Debug method.

Like this:

GameLog.LogMessage("This is a custom Log Message!");

This makes it possible to exclude debug messages from your finished game, but without needing to wrap every debug method in its own compilation check.

This works, and can be a useful way to manage excessive logging in your game so that it doesn’t hurt performance.

However, this method can still cause performance problems in your game, depending on how you’re using log messages.

This is because, while the content of the function is wrapped in a conditional check, the function itself can still be called.

Which, while this prevents the large performance overhead of using Debug Log, doesn’t avoid the potential to create garbage when defining its contents.

If you’re just using simple strings in your log messages, then this may not be a problem for you as, even though the function is still being called, surprisingly, no garbage is generated.

Unity Profiler showing no garbage

However, if you combine two strings together, as you’re likely to do when introducing game data to a debug message, the string concatenation process will create garbage, even though the function is, essentially, empty.

To avoid this, it’s possible to make the method itself conditional, meaning that it, and any calls to it, will not be compiled unless a define symbol exists, such as the UNITY_EDITOR symbol.

Like this:

[System.Diagnostics.Conditional("UNITY_EDITOR")]
    public static void LogMessage(string message)
    {
        Debug.Log(message);
    }

Or you can use a custom symbol, in which case you’ll need to enable it by adding the define preprocessor directive to the top of the script.

Like this:

#define MYSYMBOL
using UnityEngine;
public class MyClass : MonoBehaviour
{
    void Start()
    {
        GameLog.LogMessage("This will only appear if the define symbol is set!");
    }
}

This is one of the best methods for removing debug messages from a finished game because it excludes the message function and the call to it, avoiding garbage*.

What’s more, it allows you to easily enable or disable messages globally.

However, this may not be as useful to you if you’ve already added a large number of log messages to your game using Unity’s existing Debug Log function.

So how can you turn off debug messages, without using custom functions?

Option 3: Disable the Unity Logger

An easy way to disable all Debug Log functions in Unity is to simply turn off the Unity Logger.

This works by setting the Log Enabled property of the Logger to false.

Debug.unityLogger.logEnabled = false;

This works in the Editor and in standalone builds of the project and prevents all debug messages from being called, saving performance and avoiding garbage.

Typically, however,  you might only want to disable debug messages in your finished project, in which case it’s possible to enable or disable the Logger depending on if the project is a Debug Build or not.

Like this:

private void Awake()
{
    Debug.unityLogger.logEnabled = Debug.isDebugBuild;
}

This means that log messages will only be called in the Editor and in a build of the game if it’s marked as a development build.

Debug Build in Unity

Using isDebugBuild, it’s possible to enable log messages in the Editor and in Development Builds only.

However, what if you only want to disable some, but not all, log messages.

For example, you might want to keep certain messages, such as warnings and errors, in the log, so that you know if something went wrong in the build of your game.

Or you might want to disable messages relating to a particular feature that were useful while you were working on it, but are, now, just cluttering up the Console.

How can you categorise different messages into groups so that you can turn some of them off but leave others on?

How to turn off some, but not all, Debug Log messages in Unity

In the same way that it’s possible to disable the default Unity Logger, it’s possible to create new Logger instances, that can be used to categorise log messages into different groups, and then turn them on or off as you like.

This is useful, as it allows you to separate the messages that you use during development from the errors and the warnings that you might need to be able to check for in a build.

Here’s how it works.

To make a new Logger, create a new Logger instance that is public and static so that any script can access it.

Like this:

public static class Logging
{
    public static Logger myLogger = new Logger(Debug.unityLogger.logHandler);
}

To initialise the Logger instance, you’ll need to pass in a Log Handler, which manages saving log messages to a file on your computer’s hard drive.

In this example, I’m using the same Log Handler as the default Logger, meaning that, even though the log messages can be enabled or disabled separately, they’ll still be written to the same log file.

Once you’ve created a new Logger, you can use it to create debug messages with the Logger’s Log function, which works in the same way as Debug Log does.

Like this:

Logging.myLogger.Log("This message uses my custom Logger");

Setting up your own Loggers in this way allows you to enable or disable specific logging functions in your finished game and in the Editor.

For example, you could create different logging categories for combat, for your player, or for any other feature that might require extensive logging but that you’d like to have the option of turning off later on.

For this to work, create new Loggers for any categories of logging that you want to be able to separate and create a static function, in the same class (so that it’s easy to find and modify), that will specify if they are enabled or disabled.

public static class Logging
{
    public static Logger combatLogger = new Logger(Debug.unityLogger.logHandler);
    public static Logger playerLogger = new Logger(Debug.unityLogger.logHandler);
    public static void LoadLoggers()
    {
        // Call this function when the game starts
        combatLogger.logEnabled = true;
        playerLogger.logEnabled = true;
    }
}

Then, to set your debugging preferences, call the Load Loggers function when the first Scene loads.

Like this:

public class LoadLoggers : MonoBehaviour
{
    private void Awake()
    {
        Logging.LoadLoggers();
    }
}

Enabling or disabling groups of log messages in this way can be an efficient method for managing debug functions in your game.

However, while this method prevents the processing and garbage overheads of using the Debug Log function, just like when using conditional statements inside of a function, it doesn’t prevent garbage from being created when it’s called.

Meaning that, if you’re passing concatenated strings to the Debug Log function, it will still create some garbage.

As a result, if it’s an option for you, the best method for managing debug messages inside of a finished game is to exclude them from compilation entirely, by calling a custom function with a conditional attribute.

Now it’s your turn

Now I want to hear from you.

How are you debugging your project?

Are you using a custom Logger?

Or have you created your own debug functions?

And what have you learned about debugging in Unity that you know other people will find useful?

Whatever it is, let me know by leaving a comment below.

Get Game Development Tips, Straight to Your inbox

Get helpful tips & tricks and master game development basics the easy way, with deep-dive tutorials and guides.

My favourite time-saving Unity assets

Rewired (the best input management system)

Rewired is an input management asset that extends Unity’s default input system, the Input Manager, adding much needed improvements and support for modern devices. Put simply, it’s much more advanced than the default Input Manager and more reliable than Unity’s new Input System. When I tested both systems, I found Rewired to be surprisingly easy to use and fully featured, so I can understand why everyone loves it.

DOTween Pro (should be built into Unity)

An asset so useful, it should already be built into Unity. Except it’s not. DOTween Pro is an animation and timing tool that allows you to animate anything in Unity. You can move, fade, scale, rotate without writing Coroutines or Lerp functions.

Easy Save (there’s no reason not to use it)

Easy Save makes managing game saves and file serialization extremely easy in Unity. So much so that, for the time it would take to build a save system, vs the cost of buying Easy Save, I don’t recommend making your own save system since Easy Save already exists.

Additional Credits

  • Many thanks to Daniel in the comments, who pointed out that calls to a disabled logger / custom functions can still cause garbage.

TL;DR When debugging Unity WebGL apps, use the web browser’s developer tools. For Chrome browsers press the F12 key – for other browsers see below in the browser section. Unity Debug.Log*() calls redirect to the browser’s dev tools console. With that being said, if you have the spare time and want a more elaborate deep-dive into the subject, the rest of the article awaits.

A big part of developing any app is debugging it – often, that involves logging. So I don’t think anyone will argue when I say that a significant part of Unity development is using the Debug log functions (i.e. Debug.Log(), Debug.LogWarning(), Debug.LogError()).

Normally we can debug and view logs from the Unity editor while developing. But there are situations where we may need to see log messages during run-time. What happens if we need to view the Debug.Log output when the app is built to WebGL? The answer: use the browser’s debug console.

Browser Development/Debug Tools

For those building to Unity WebGL that don’t have a web development background, here’s a world-altering crumb of information: all the major desktop browsers have mature debugging suites. Some have them built straight into the browser, others have these debug tools as (official) plugins.

  • For Chrome: the dev tools are toggled with the F12 key.
  • For Edge: the dev tools are a separate free app in the Microsoft store.
  • For Firefox: the dev tools are toggled with the F12 key.
  • For Opera: the dev tools are available as an extension and toggled with the F12 key.
  • For Internet Explorer: … dude,… no… treat yourself better!

The Console

For the rest of the post I’m going to use Chrome. For non-Chrome developers, you will need to use your imagination a bit and use your browser’s equivalent features.

Again, pressing the F12 key will bring up the developer tools for Chrome.

When opening the dev tools, there are some tabs. The relevant tab for viewing log information is the Console tab, which has a text log. These log entries are the messages, warnings, and errors of various things, all readable in one location – very similar to the Unity editor’s console. These entries are either raised from the browser itself or the site’s Javascript by calling console.log().

The developer tools is docked to the right side of my browser when I press F12. I then make sure it’s on the Console tab so I can see the log.

Viewing Debug Logs In The Console

With all this prerequisite information out of the way, here’s the good news: Unity WebGL apps are already set up to redirect Debug.Log* functions to the browser’s console log.

Let’s bring up the test app for some examples. First the snippet of code used to embed it, and then the embedded instance. The Log, Warning, and Error buttons will call the Debug.Log*() functions with simple messages. Test it with your developer’s tool console open.
Note the app will also catch these debug messages and show them in a text field in GUI.

That common utility file we always have to include, UnityProgress.js, has JavaScript functions that are delegated from the Unity Debug.Log*() functions and they call console.log(). If we look at a beautified version of the file here, we can see around line 2691,

...
print: function(e)
{
	console.log(e)
},
printErr: function(e)
{
    console.error(e)
},
Jobs:
...

Beautifier.io was used to beautify the UnityProgress.js example.

Calling Debug.Log*() functions and seeing the log messages in the Chrome browser console. This screenshot was taken with an earlier version of the WebHalt app.

For reference, here’s the snippet in the sample app that’s calling Debug.Log*() in the UI. It’s exactly what you’d expect

// In Console.cs (See the end of this article for a page with
// a download link to the project source.)
...
public class Console : MonoBehaviour
{
    ...
    private void OnGUI()
    {
        ...
            GUILayout.BeginHorizontal();
                if(GUILayout.Button("Log") == true)
                    Debug.Log("A Debug.Log() call");
                if(GUILayout.Button("Warning") == true)
                    Debug.LogWarning("A Debug.Warning() call");
                if (GUILayout.Button("Error") == true)
                    Debug.LogError("A Debug.Error() call");
                if(GUILayout.Button("Clear") == true)
                    this.log = string.Empty;
            GUILayout.EndHorizontal();
        ...
        GUILayout.EndVertical();
    }
}

Issues

There’s an article from 2016 that mentions how exceptions don’t log exceptions from coroutines. It still appears to be an issue. If you press the Start Coroutine button to get the text bar to move and press the Exception on coroutine button, the thrown exception will be shown in the Unity editor, but not shown in the console for WebGL builds, even though non-coroutine exceptions are shown. But then again, coroutines seem to have multiple quirks in WebGL builds.

Conclusion

That’s pretty much it. Just remember when looking at the log messages in the browser’s debug console, it’s the browser’s log for everything, not just your log messages. You’ll see debug log output for the browser, the website, and any 3rd party Javascript libraries. So pay attention to where various messages are coming from when skimming them while debugging.

Information on the sample WebGL app can be found here.
Built with Unity 2018.3.8f1
Authored and tested with Chrome
– Stay strong, code on. William Leu

More articles here. More articles about Unity WebGL here.

Понравилась статья? Поделить с друзьями:

Читайте также:

  • Debug console mod error pattern mismatch 0 1 h ведьмак 3 что делать
  • Debug assertion failed visual c как исправить line 904
  • Debug assertion failed visual c как исправить gta sa
  • Debootstrap error release file signed by unknown key
  • Debian проверка диска на ошибки

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии