Introduction

SRDebugger is a suite of tools to help you fix bugs and iterate gameplay ideas while on your target platform. Having access to the Unity Console in any build of your game while on-device allows you to investigate bugs without deploying a debug build tethered to your computer. The options tab can help you find the perfect parameters for gameplay features by tweaking them in realtime on the destination platform (for example: drag-sensitivity, zoom speed, smoothing factor).

Getting Started

Quick setup and easy configuration were important goals when designing SRDebugger.

Unity 5

After importing the package from the Unity Asset Store the debugger will be accessible in all scenes of your game automatically. See configuration if this behaviour is undesirable and you wish to manually start SRDebugger.

Unity 4

Import the package from the Unity Asset Store, and then drag the SRDebugger.Init prefab (located in StompyRobot/SRDebugger folder) into the first scene of your game. The overhead for SRDebugger is negligible until the debug panel is opened (and even once opened, is very small), so there will be no noticeable increase in loading times if you put the SRDebugger.Init prefab in the first scene of your game. This will ensure that the maximum number of initialisation logs will be present for when you open the debugger later. Once SRDebugger is loaded, it will be available in all subsequent scenes of your game.

Opening the Debug Panel

SRDebugger includes a simple, non-obstrusive trigger button to provide access to the debug panel on mobile devices. By default, the trigger is placed in the top-left corner of the game window and can be triple-tapped to open the panel. You can disable the trigger or change the position in the settings window (see configuration).

On platforms with a keyboard, you can setup keyboard shortcuts to open and close the debug panel and control various functions of SRDebugger.

You can also open the debug panel from code. See the API section.

Default Shortcuts

Key Combination Action
Ctrl-Shift-F1 Open System Tab
Ctrl-Shift-F2 Open Console Tab
Ctrl-Shift-F3 Open Options Tab
Ctrl-Shift-F4 Open Profiler Tab
Escape Close Debug Panel

Configuration

The SRDebugger Settings window can be accessed in the menubar (Window/SRDebugger Settings).

General

Loading

Disabled SRDebugger will not load until a manual call to the SRDebug.Init() API method.
Prefab Place the SRDebugger.Init prefab (found in the asset folder) into the scene to load SRDebugger
Automatic SRDebugger will load automatically when your game starts (default)

Panel Access

Trigger Mode Always: Trigger will always be available, Mobile Only: Trigger will only appear on mobile platforms, Off: Trigger will never appear.
Trigger Behaviour Select how the trigger is activated, either Triple-Tap or Tap-and-Hold.
Default Tab Select the tab that will appear first when the debug panel is opened.
Require Entry Code Check to require the user to enter a code before accessing the debug panel for the first time (check every time to require the pin every time).

Layout

Use the dropdown menus to rearrange the positions of the docked tools and trigger.

Bug Reporter

See Bug Reporter.

Advanced

Console

Collapse Log Entries Duplicate log entries will be grouped in the same row in the console, with a badge indicating how many times it occured. Similar to the Unity Editor console Collapse mode.
Rich Text in Console Enable rich text support in console messages.

Display

Background Transparency If enabled the background of the debug panel will be semi-transparent.
Collapse Log Entries Duplicate log entries will be grouped in the same row in the console, with a badge indicating how many times it occured. Similar to the Unity Editor console Collapse mode.
Rich Text in Console Enable rich text support in console messages.
Layer Select the layer that the UI should be placed in. Defaults to the build-in UI layer.
Use Debug Camera By default, SRDebugger uses the Overlay render mode. If this option is selected, SRDebugger will create a camera with the depth provided. You can use this to control what renders on top of the SRDebugger UI.

Console

The console tab hooks into the default Unity Log system. Any calls to Debug.Log, Debug.LogWarning, Debug.LogError will appear here.

Select a log entry to view the full message and stack trace (if available on the target platform).

You can filter the visible log types with the buttons on the toolbar at the top of the screen. Press the Trash icon to clear the log. The Pin button will dock the console to the game view, press again to undock.

Options Tab

It can be incredible useful to be able to modify gameplay parameters while on the target device. The Options Tab enables this by scanning for properties and methods in the built-in SROptions class.

SROptions is declared as a partial class, which allows you to split the class over multiple files. We advise creating a new file for each category of option, for example: SROptions.Gameplay.cs, SROptions.Debug.cs, SROptions.Cheats.cs.

Inside these files you should declare a class with the following signature:

public partial class SROptions { }

We will populate this class with properties and methods to build up the options menu.

Example SROptions class

Let’s begin with a full example of how an options class might look.

public partial class SROptions {

	// Default Value for property
	private float _myProperty = 0.5f;
	
	// Options will be grouped by category
	[Category("My Category")] 
	public float MyProperty {
		get { return _myProperty; }
		set { _myProperty = value; }
	}
	
	private float _myRangeProperty = 0f;
	
	// The NumberRange attribute will ensure that the value never leaves the range 0-10
	[NumberRange(0, 10)]
	[Category("My Category")]
	public float MyRangeProperty {
		get { return _myRangeProperty; }
		set { _myRangeProperty = value; }
	}
	
}

You can access these properties in code via the SROptions.Current static property.

transform.position = new Vector3(0, 0, SROptions.Current.MyProperty);

Properties

SRDebugger will scan the SROptions class for compatible properties automatically and include them in the Options Tab.

There are two ways of tying these properties into your own game code.

  1. Reference the property directly in script. e.g. transform.Translate(SROptions.Current.MySpeedProperty * Time.deltaTime, 0, 0);

  2. Implement custom object lookup the property get/set methods, to find and modify objects in the scene.

// Simplified example - it is a good idea to handle cases where MyComponent is not found.
public float MyCustomProperty {
	get { return GameObject.FindObjectOfType<MyComponent>().SomeField; }
	set { GameObject.FindObjectOfType<MyComponent>().SomeField = value; }
}

For most cases, #1 would be the most appropriate approach. #2 is useful when you wish to affect code that you do not control, for example a library contained in a .dll file.

For more examples, look in StompyRobot/SRDebugger/Scripts/SROptions.Test.cs

Supported Types

Properties of the following types are supported: Boolean, Enum, int, uint, short, ushort, byte, sbyte, float, double, and string.

Read Only

Read only properties (missing or non-public setter method) will appear in the options tab, but are not able to be changed. This can be used to display debug information to the user. The property value will be rechecked whenever the options tab is opened, but you can use OnPropertyChanged to manually refresh the value.

OnPropertyChanged

The OnPropertyChanged callback will cause SRDebugger to check for new values for properties. If you don’t implement this callback, updates to SROptions properties will only be reflected in the options tab each time it is opened. With this callback implemented any updates to properties will appear instantly.

private int _netBytesIn;
 
[Category("Net")]
public int NetBytesIn {
    get { return _netBytesIn; }
    set {
        _netBytesIn = value;
        OnPropertyChanged("NetBytesIn");
    }
}

Methods

Any public methods in the SROptions class with no parameters and a void return type will appear in the options panel as buttons. When pressed, the method will be invoked dynamically. Category attributes can be applied to methods to group them as with properties.

using System.ComponentModel;
using UnityEngine;

public partial class SROptions {
	[Category("Utilities")] // Options will be grouped by category
	public void ClearPlayerPrefs() {
		Debug.Log("Clearing PlayerPrefs");
		PlayerPrefs.DeleteAll();
	}
}

Pinning

Options can be pinned to the game view by pressing the Pin button when on the options tab and selecting the options you wish to appear. These options can then be modified without entering the debug panel. A thick border will appear to indicate an options Pinned state.

To unpin an option, press the Pin button and tap the option. The border will disappear, indicating that the option is no longer pinned.

It is also possible to pin/unpin options via the API.

Attributes

You can use the built-in attributes to change how the user can interact with your options.

Attribute Description
NumberRange Limits a number property to the range provided.
Increment Changes how much a number property is changed by pressing the up/down buttons on the options tab.
DisplayName Manually control what name the option will use on the options tab.
Sort Provide a sorting index that is used to control the order in which options appear.
Category Group options by category name. (Note: The System.ComponentModel namespace must be imported in your file to use this attribute.

Option Containers

It is possible to add your own “Option Container” objects to the Options tab. See the API section for more information.

Profiler

The profiler provides an approximation of how long each step of a frame took to execute. Note, this is not as accurate or as detailed as the Unity Editor profiler. It is only intended as a tool for identifying areas of your game that are CPU or GPU heavy.

The frame graph can be viewed on the profiler tab or docked to the in-game view. The profiler docked-state can be toggled with the Pin icon on the toolbar or via the API.

Also available is an indicator of how much memory your Unity application has allocated and in use. You can manually trigger garbage collector runs or memory cleanups from the profiler tab.

Bug Reporter

The Bug Reporter is a web service that we host, provided free to all owners of SRDebugger. User bug reports will be forwarded directly to your email address as they arrive.

A bug report consists of the console log, system information, a screen capture, and (optionally) the user’s email and message. Once setup, the bug reporter tab will be visible in the debug panel.

If you wish to use the bug reporter without providing user access to the debug panel, you can use the API to show a bug report popover sheet.

Setup

To use the bug reporter you must acquire a free API key. In the SRDebugger Settings window (Window/SRDebugger Settings), switch to the Bug Reporter tab. The form will acquire an API key for you. You will need to provide your Invoice Number from the Asset Store receipt and a valid email address that bug reports will be sent to. You will need to click the link sent to the verify the email address before you can receive any bug reports.

API

The SRDebugger API is accessed via the SRDebug.Instance static property.

Available Methods

// Current settings being used by the debugger
Settings Settings { get; }

// True if the debug panel is currently being shown
bool IsDebugPanelVisible { get; }

// True if the trigger is currently enabled
bool IsTriggerEnabled { get; set; }

// Show the debug panel
void ShowDebugPanel(bool requireEntryCode = true);

// Show the debug panel and open a certain tab
void ShowDebugPanel(DefaultTabs tab, bool requireEntryCode = true);

// Hide the debug panel
void HideDebugPanel();

// Hide the debug panel, then remove it from the scene to save memory.
void DestroyDebugPanel();

// Open a bug report popover sheet.
void ShowBugReportSheet(ActionCompleteCallback onComplete = null, bool takeScreenshot = true, string descriptionContent = null);

// Event invoked whenever the debug panel opens or closes
event VisibilityChangedDelegate PanelVisibilityChanged;

// Methods related to docking/undocking the console
IDockConsoleService DockConsole { get; }

// True if the profiler is currently docked.
bool IsProfilerDocked { get; set; }

// Add a piece of information to the System tab (also included with bug reports).
void AddSystemInfo(InfoEntry entry, string category = "Default");

// Add all the properties/methods in "container" to the options tab.
void AddOptionContainer(object container);

// Remove all the properties/methods added by "container" from the options tab.
void RemoveOptionContainer(object container);

// Pin all the options in "category"
void PinAllOptions(string category);

// Unpin all the options in "category"
void UnpinAllOptions(string category);

// Pin all the options with "name"
void PinOption(string name);

// Unpin all the options with "name"
void UnpinOption(string name);

// Unpin all options
void ClearPinnedOptions();

// ADVANCED. Will transform the debug panel canvas into a world space object and return the RectTransform.
// This can break things so only use it if you know what you're doing. It can be useful for VR, for example, attaching the panel above the user controller.
RectTransform EnableWorldSpaceMode(); // (Added in 1.6.0)

Options Containers

An Options Container is simply a normal C# object. All the usual SROptions supported types and restrictions apply, except that you handle the creation of the object. Options containers can be added or removed at any time. If the container object implements the INotifyPropertyChanged interface, and properties call the OnPropertyChanged method, any changes you make via code will be reflected in the SRDebugger Options panel.

Example

Adding option containers for specific levels

Some options might only be relevent to certain levels of your game. You can use the “Option Containers” API to add/remove options at runtime.

// sceneOptions represents your own management system for the options objects.
var sceneOptions = new Dictionary<Scene, object>();

SceneManager.sceneLoaded += (scene, mode) =>
{
    if (sceneOptions.ContainsKey(scene))
    {
        SRDebug.Instance.AddOptionContainer(sceneOptions[scene]);
    }
};

SceneManager.sceneUnloaded += scene =>
{
    if (sceneOptions.ContainsKey(scene))
    {
        SRDebug.Instance.RemoveOptionContainer(sceneOptions[scene]);
    }
};

Options containers contained in a custom .dll

If using your own DLLs for game logic, it is not possible to use the same partial class system the default SROptions object uses. Instead, you can create your own options object and register it with the API.

// In MyGameCode.dll
class MyOptions {
	public static readonly MyOptions Instance = new MyOptions();

	public void SomeAction() { /* ... */ }
	public float SomeProperty { get; set; }
}

// In Unity
SRDebug.Instance.AddOptionContainer(MyOptions.Instance);

Examples

Opening debug panel on options tab

SRDebug.Instance.ShowDebugPanel(DefaultTabs.Options);

Hiding debug panel

if(SRDebug.Instance.IsDebugPanelVisible)
	SRDebug.Instance.HideDebugPanel();

Showing bug report popover

SRDebug.Instance.ShowBugReportSheet();

Showing bug report popover with callback

SRDebug.Instance.ShowBugReportSheet(success => Debug.Log("Bug Report Complete, Success: " + success));

Showing bug report popover with default description

SRDebug.Instance.ShowBugReportSheet(descriptionContent: "This will be placed in the description field.");

Toggling the docked console

SRDebug.Instance.DockConsole.IsVisible = !SRDebug.Instance.DockConsole.IsVisible;

Toggling the docked console collapsed state

SRDebug.Instance.DockConsole.IsExpanded = !SRDebug.Instance.DockConsole.IsExpanded;

Toggling the profiler docked state

SRDebug.Instance.IsProfilerDocked = !SRDebug.Instance.IsProfilerDocked;

Custom action when debug panel opens/closes

Some games use input methods which aren’t suitable for navigating the debug panel UI (e.g. VR or 1st-person shooters). In these cases, you can subscribe to the PanelVisibilityChanged event to enable a suitable input method only when the debug panel is visible.

SRDebug.Instance.PanelVisibilityChanged += visible => {
    // Handle panel visibility changing here.
    Debug.Log("IsVisible: " + visible);
};

Entry Code

You can use the same entry code form that SRDebugger uses to control access to parts of your game.

using SRDebugger.Services;
using SRF.Service;
using UnityEngine;

public class PinSample : MonoBehaviour
{
    void Start()
    {
        // Pin must be 4-digits, 0-9
        SRServiceManager.GetService<IPinEntryService>().ShowPinEntry(new [] {3,0,5,6}, "Message to user here", OnComplete);
    }

    private void OnComplete(bool validPinEntered)
    {
        if (validPinEntered)
        {
            // User entered a valid code
        }
        else
        {
            // User entered invalid code
        }
    }
}

Support

FAQ

Q: My game responds to input while the debug panel is open. How can I stop this?

A: Use the IsPointerOverGameObject() method to filter input that is blocked by a UI element. (See here for details.)

Q: My game crashes on iOS after importing SRDebugger

A: If you’re using the IL2CPP scripting backend you should upgrade to the latest version of Unity. This has some key fixes to reflection that SRDebugger depends on.

Q: I’m getting an error about CategoryAttribute not found

A: Import the System.ComponentModel namespace in your script file containing SROptions.

Direct Support

Email contact@stompyrobot.uk with any support questions, or post in the Unity Forum Thread.