Key features

Easy to use - Simply attach a script and select which events you want to log or sprinkle your scripts with EZ.Log if you want more control

Performance - You can store tens of thousands messages without framerate drops

Customizable windows - Drag, resize, dock or hide windows so they're not getting in your way

Advanced filtering - Filter by message, severity, game object or custom labels to only show what's important

Hot reloading support - If you change your code during gameplay EZLogger will still work without problems

Installation

1. Import the EZLogger package into your project

2. Choose one of the options below

  • a) Either add the EZLogger to the scene by using Unity menu.

  • b) Or manually add the prefab to the scene

  • c) Or do nothing. The EZLogger will be added to the scene automatically during runtime if used by any script (or attached helper component)

Usage with helper component

You can use provided helper component to easily log Unity events. Simply attach "EZ Log Helper" to any game object in the scene

Event list is split into categories so you can choose to only see the ones you're interested in. Names of events correspond directly to Unity "On<Event>"

Select the events you're interested in and optionally set custom message. For each event you can choose the severity of log message - debug, info, warning or error. Unselect "Is Active" to disable all logging from that object

Above setting would result in something like this. Note that the game object's name was added automatically so there's no need to use it inside the message

You can set logging for multiple objects at once, just select them in the hierarchy window. You'll see a message next to the event if the settings are not identical across all objects. Any change that you make will be applied to all selected objects

Usage within scripts

If you need more control over the logging you can use methods from EZ class inside your code. All methods there are public and static so you don't need to instantiate anything.

For most basic logging just use EZ.Log with message passed as only argument

    EZ.Log("Hello I'm a log message");

Here is the full API that can be used to log your messages

    void Log(string text);
    void Log(string text, string[] tags);
    void Log(string text, string tag);
    void Log(string text, EZLogSeverity severity);
    void Log(string text, EZLogSeverity severity, GameObject gameObject);
    void Log(string text, EZLogSeverity severity, GameObject gameObject, string[] tags);
    void Log(string text, EZLogSeverity severity, GameObject gameObject, string tag);
    void Log(string text, EZLogSeverity severity, string[] tags);
    void Log(string text, EZLogSeverity severity, string tag);
    void Log(string text, GameObject gameObject);
    void Log(string text, GameObject gameObject, string[] tags);
    void Log(string text, GameObject gameObject, string tag);

    void Debug(string text);
    void Debug(string text, string[] tags);
    void Debug(string text, string tag);
    void Debug(string text, GameObject gameObject);
    void Debug(string text, GameObject gameObject, string[] tags);
    void Debug(string text, GameObject gameObject, string tag);

    void Info(string text);
    void Info(string text, string[] tags);
    void Info(string text, string tag);
    void Info(string text, GameObject gameObject);
    void Info(string text, GameObject gameObject, string[] tags);
    void Info(string text, GameObject gameObject, string tag);

    void Warning(string text);
    void Warning(string text, string[] tags);
    void Warning(string text, string tag);
    void Warning(string text, GameObject gameObject);
    void Warning(string text, GameObject gameObject, string[] tags);
    void Warning(string text, GameObject gameObject, string tag);

    void Error(string text);
    void Error(string text, string[] tags);
    void Error(string text, string tag);
    void Error(string text, GameObject gameObject);
    void Error(string text, GameObject gameObject, string[] tags);
    void Error(string text, GameObject gameObject, string tag);

    void Peek(string label, object value);
    void Count(string label);
                

Log.Debug, Log.Info, Log.Warning and Log.Error are just wrappers for Ez.Log with EZLogSeverity enum set to proper value. If you use EZ.Log without passing severity argument EZLogSeverity.Info will be used so these three lines are working exactly the same:

    EZ.Log("Some message");
    EZ.Log("Some message", EZLogSeverity.Info);
    EZ.Info("Some message");
                

If you pass gameObject argument then it'll be associated with that message. The name of the object will be displayed next to the message if the "Toggle log entry game object" is enabled. The object will also appear in tags and game objects panel.

Please note that two different game objects with the same name will be treated separately, EZLogger uses instance id under the hood to decide if it's the same object.

    EZ.Log("Message without game object");
    EZ.Log("Message with game object", gameObject);
                    

If you pass tag or tags argument then those tags will be associated with that message. Two tags with the same name are identical.

    EZ.Log("Message without game object", "my tag");
    EZ.Log("Message with game object", gameObject, new [] { "my tag", "another tag" });
                    

If you don't provide neither gameObject nor tag/tags then the message will be associated with (default) tag.

There are two methods in API that do not log the message like in examples above.

    void Peek(string label, object value);
    void Count(string label);
                    

Instead EZ.Peek and EZ.Count are used to track values and count events. The label is the name that will be displayed in the window, value can by anything, if it's an object or struct that implements .toString() method then it'll be used to determine the value. EZ.Peek is useful if you're only interested in current/last value of some variable like position.

    private void Update()
    {
        EZ.Peek("Mouse position", Input.mousePosition);
        EZ.Peek("Time since start", Time.time);
    }

    private void OnMouseDown()
    {
        EZ.Peek("Last click time", Time.time);
    }
                    

EZ.Count is useful for counting how many times something happened.

    private void OnCollisionEnter(Collision collision)
    {
        EZ.Count("Times collided");
    }
                    

Please note that the label passed to EZ.Peek and EZ.Count has to be unique, if you use the same name for tracking different object/event then the values will be overwritten.

EZLogger log window

Log panel

The log panel holds all of your logged messages. It implements virtualization, that means that even though you may have thousands of messages only the ones that should be visible on the screen are rendered. This makes the EZLogger very fast as it doesn't have to render or recalculate positions of messages that are outside of the current view. There is one drawback to this approach - all lines need to have the same height for the calculations to work properly. That means that if the message is longer than the width of the log panel it's not wrapped to next line - you have to use horizontal scroll (that will appear automatically) to see the full message. This is on my TODO list and I hope to add option for wrapping messages in future update.

Messages are rendered in the order in which they were added, oldest on top. If there are more messages than current height of the log panel can handle, vertical scroll will appear. You can scroll messages either by clicking and dragging the scroll handle or use mouse scrollwheel.

Unless you scroll up, when new message is rendered the whole viewport is scrolled to bottom so can always see new messages. This is very similar to how Unity Editor console works.

Toolbar

Toolbar contains controls for different actions. It is rendered above the log panel unless it's docked to top in which case it is rendered below the log panel.

Removes all messages logged so far. All game objects and tags are also cleared.

These can be toggled on/off, if toggled off then the corresponding severity messages will be hidden from the log panel. For example you can log a lot of detailed information with debug severity but only show them when you need to.. well debug something :)

Use these to dock the EZLogger window to top/bottom or to set the window "free". When the window is docked it can't be dragged around and it can only be resized in one direction. When the window is undocked it can be dragged freely and resized in all directions. When the window is docked to top the toolbar is placed below the log panel.

Use this text field to only show messages that contain the phrase. Toggle the case sensitive button if you care about case sensitivity. Click the x icon to remove the filter.

Toggle these controls to hide/show additional information associated with the message. Any configuration is fine, you can have none, all or anything in between

  • Index
  • Time when the message was added - formatted HH:mm:ss.fff, customization options will be added in future update
  • Frame number - the frame on which the message was added, uses Unity's Time.frameCount
  • Game object name - if there is a game object associated with this message then its name is displayed

(yes, it's late)

Use this to show/hide the...

Game objects and tags panel

Here you can see all game objects and tags that you've associated with your messages. Use this panel to filter the log messages so only messages about specific objects/tags are shown. Next to object/tag name you can see how many associated messages were logged, grouped by severity.

Please note that if there is more than one object/tag associated with the message it will be shown if ANY of those object/tags are enabled.

    EZ.Log("I'm a message with gameObject", gameObject);
    EZ.Log("I'm a message with tag", "tag");
    EZ.Log("I'm a message with both", gameObject, "tag");
                

By default all objects/tags are visible.

If you hide Blue Wall object then the message with ONLY that object is hidden, the message that has both game object and tag is still visible.

Same thing with tags.

If you hide both game object and tag then all three messages disappear.

(default) works the same way, it hides/shows the messages don't have neither game object nor any tags associated with them.

Use this to hide/show all objects/tags. Useful if you only want to see one thing and don't want to hide everything manually.

Filter works the same way as in log panel. Please take note that it only filters the objects/tags by name, it doesn't automatically hide the messages associated with them. Option to do that will implemented in future update.

Peeks and counts window

EZLogger has separate windows for tracking EZ.Peek and EZ.Count uses. It can be freely dragged around and resized.

Use this field to filter the peeks/counts by name. Works the same way as filter field in log panel.

You can either reset all of the counters by clicking the reset button in the toolbar, or just a single counter by clicking the reset button next to its value. Reset counter will have its value set to 0.

Removes and ignores all future peeks or counts with that name. Currently there is no way to bring back removed peek/count, this feature will be added in future update.