UDebug Panel is a lightweight and versatile ingame debug panel for Unity with C#. It can be incredible useful to be able to modify gameplay parameters while on the target device. This asset simplifies the process of creating a panel with debut options in your Unity projects, allowing you to focus on what matters: gameplay.
A debug panel, is a user interface that provides developers with tools and information to aid in debugging and profiling during the development of a software application or game.
This asset provides a suit of premade elements (buttons, int selector, float selector, enum selection, etc), while allowing for the creation of new ones, with ease.
If you find any issue, please report it here.
- Features
- Installation
- After Installing
- Getting Started
- Sections
- Automatic Debug Actions
- Manual Debug Actions
- Custom Debug Actions
- Build Stripping
- Rate Asset
-
Simple API: Unity Debug Panel provides an intuitive and easy-to-use API with C#.
UDebugPanel.Show(); UDebugPanel.Hide(); IDebugActionsSection section = UDebugPanel.AddSection("Section name"); section.AddButton("Button name", () => Debug.Log("Button click"));
-
Adaptative: The different widgets support and adapt to different screen aspect ratios, making it a good fit for both, desktop and mobile.
-
Smart: You can automatically generate a debug options section using a class. Using reflection, changes that occur on the debug panel will affect the class instance.
-
Organization: Organize your options using sections.
-
Fuzzy search: Quickly find the options you were looking for with the search bar!
-
Lightweight: While your game is running, the panel does not exist at all until you want to show it. When is hidden again, the panel is completely destroyed, so it does not impact the performance of your game.
Download and import from the Unity Asset Store. You can move the root folder anywhere you want in your project. The package has the following dependencies:
- TextMeshPro (Mandatory).
Note
If you are using Assembly Definitions, you may need to include the DebugPanel.Runtime assembly to your assemblies.
Note
Works with both New and Old Input Systems.
To quickly check if everything has been setup properly, you can go to DebugPanel/Examples/Scenes/ and open any of the example scenes. When you run any of those scenes, a simple functionality example should play.
- For showing the panel, you just need to call the
Showmethod. The internal logic will take care of everything else.UDebugPanel.Show();
- For hiding the panel, just call the
Hidemethod.UDebugPanel.Hide();
- For convenience, you can also toggle the panel. Just call the
Togglemethod.UDebugPanel.Toggle();
We already provide some handy automatic input toggles for you.
UDebugPanel.SetupToggleInput();By calling UDebugPanel.SetupToggleInput(), you will automatically setup toggle for:
- Keyboard F1 key.
- Middle mouse button.
- Triple finger tap on screen.
You can modify this behaviour using the method parameters.
The panel has support for navigation with a controller or keyboard. You can enable controller navigation by calling:
UDebugPanel.SetControllerSupport(true);Note
Must be called before showing the panel, to take effect.
Debug actions are divided within different sections. These sections allow you to better organize your actions. You cannot create a debug action outside of a section.
- Creating a new section is very simple, you just need to call
AddSectionand provide a section name:IDebugActionsSection section = UDebugPanel.AddSection("Section name");
- Removing a section is equally as simple. Just call
RemoveSection, and provide the section you want to remove.UDebugPanel.RemoveSection(section);
Note
You don't need to show the panel before creating actions/sections.
Note
You can see this functionality on the example DebugPanel.Sections.
This asset has the ability of scanning for properties and methods in C# classes, to automatically create the adecuate widgets. By default, only public properties are used for creating debug actions, the rest are ignored (unless specified with the attribute ShowAsDebugAction).
One of such classes may look like this:
class Options
{
[NumberStep(5)]
public int IntProperty { get; set; }
[NumberStep(2.5f)]
public float FloatProperty { get; set; }
[NumberRange(-10, 10)]
public long LongProperty { get; set; }
[DisplayName("Bool Property Custom Display Name")]
public bool BoolProperty { get; set; }
public EnumProperty EnumProperty { get; set; }
public string StringValue { get; } = "Text";
public int IntValue => IntProperty;
public float FloatValue => FloatProperty;
public long LongValue => LongProperty;
public bool BoolValue => BoolProperty;
[DontShowAsDebugAction]
public EnumProperty EnumValue => EnumProperty;
[ShowAsDebugAction]
EnumProperty PrivateEnumValue { get; set; }
public void Method()
{
Debug.Log("Calling Method");
}
[ShowAsDebugAction]
void PrivateMethod()
{
Debug.Log("Calling Private Method");
}
[Category("Another Section")]
public int IntProperty2 { get; set; }
[Category("Another Section")]
public int FloatProperty2 { get; set; }
}Then we add the class like this:
UDebugPanel.AddOptionsObject(new ExampleOptionsObject());And we will get debug options like this:
You can also use static classes to define your debug actions, by using the attribute [DebugActionsObject].
Then, call UDebugPanel.AddGlobalOptionsObject() once to automatically add all the static classes with the attribute as debug actions.
[DebugActionsObject]
static class OptionsAutomatic
{
public static int IntProperty { get; set; }
[NumberStep(2.5f)]
public static float FloatProperty { get; set; }
[NumberRange(-10, 10)]
public static long LongProperty { get; set; }
}Then we add all the classes like this:
UDebugPanel.AddGlobalOptionsObjects();We provide several attributes to add felxibility to the automatic debug actions creation:
- DisplayName: Sets a custom name for your debug action.
- Category: Sets the section where the debug action will be created.
- NumberStep(number): for number properties (int, float, long), allows to set the step used when clicking on the widget left or right arrows.
- NumberRange(numberMin, numberMax): for number properties (int, float, long), allows to set a minimum and maximum value on the widget.
- ShowAsDebugAction: Cretes the debug action when the property is private.
- DontShowAsDebugAction: Does not create the debug action when the property is public.
Note
You can see this functionality on the example DebugPanel.Reflection.
This is the most important part of this asset, the debug actions (or widgets). Once you have a section, you add debug actions to it:
-
Info: a static string that cannot be changed one submited.
section.AddInfo("Some info that never changes");
-
Dynamic Info: a getter for a string that it's updated every frame.
section.AddInfoDynamic(() => "Some info that can change");
- Toggle: a simple bool toggle with a name. Requests a setter and a getter for the value.
bool someBool = false; section.AddToggle("Toggle name", val => someBool = val, () => someBool);

-
Int: an int selector with a name. Requests a setter and a getter for the value.
int someInt = 0; section.AddIntSelector("Int name", val => someInt = val, () => someInt);
-
Float: a float selector with a name. Requests a setter and a getter for the value.
float someFloat = 0f; section.AddFloatSelector("Float name", val => someFloat = val, () => someFloat);
-
Long: a long selector with a name. Requests a setter and a getter for the value.
long someLong = 0; section.AddLongSelector("Long name", val => someLong = val, () => someLong);
-
Button large info: a button that opens a popup which can show information as text.
section.AddButtonLargeInfo("Button name", () => "This is some large info");
-
Button string input: a button that opens a popup where you can set a string value.
section.AddButtonStringInput("Button name", () => "Empty", v => Debug.Log($"Selected {v}");
-
Button string selector: a button that opens a popup where you can select a string value. The current selected value is stored and shown on the button text.
string _stringValue= "Empty"; section.AddButtonStringSelector("Button name", () => _stringValue, v => _stringValue = v);
-
Button list input: a button that opens a popup where you can select an item from a list of items.
List<string> _elementsList = new() {"Element1", "Element2", "Element3"}; section.AddButtonListInput("Button name", () => _elementsList, i => Debug.Log($"Selected {_elementsList[i]}"));
-
Button list selector: a button that opens a popup where you can select an item from a list of items. The current selected value is stored and shown on the button text.
List<string> _elementsList = new() {"Element1", "Element2", "Element3"}; section.AddButtonListSelector("Button name", () => _elementsList, i => Debug.Log($"Selected {_elementsList[i]}"));
-
Button enum selector: a button that opens a popup where you can select the value of an enum. The current selected value is stored and shown on the button text.
TestEnum _elementEnumSelected = TestEnum.Element1; section.AddButtonEnumSelector("Button name", i => _elementEnumSelected = i, () => _elementEnumSelected);
- Nested conatiner: a button that opens a popup which can have more debug actions.
section.AddButtonActionsContainer("Actions", s => { s.AddButton("Another Button 1", () => Debug.Log("Button pressed")); s.AddButton("Another Button 2", () => Debug.Log("Button pressed")); s.AddButton("Another Button 3", () => Debug.Log("Button pressed")); });

Note
You can see debug actions functionality on the example DebugPanel.Widgets.
Some times, your game may have specific needs that cannot be properly met by the default provided widgets. That's why you can create your own. We are going to use the Info action as an example.
-
The first thing you need to do is create a new class and inherit from
DebugAction. This interface will force you to implementDebugActionWidget InitWidget(DebugActionWidget viewInstance)method, which is responsable for setting the values from the action, to the widget Ui. We will not implement it for now. We should first set the information that the action will hold. In this case it's a string for the info.public sealed class InfoDebugAction : DebugAction { readonly string _info public InfoDebugAction(string info) { _info = info; ActionName = info; // ActionName is used for search box functionality } public override void InitWidget(DebugActionWidget viewInstance) { throw new NotImplementedException(); } }
-
Next, we need a new
DebugActionWidget, which will be the actual GameObject placed on the Ui. Since the widget is made of a label, we will add a reference to it. We will also add an Init method to set the label value.public sealed class InfoDebugActionWidget : DebugActionWidget { public TextMeshProUGUI Label; public void Init(string info) { Label!.text = info; } }
-
Going back to the
InfoDebugActionclass, we need to implementInitWidget. The widget itself will be automatically instantiated internally. We need to init it here.public sealed class IntDebugAction : IDebugAction { readonly string _info public InfoDebugAction(string info) { _info = info; ActionName = info; } public override void InitWidget(DebugActionWidget viewInstance) { InfoDebugActionWidget widget = (InfoDebugActionWidget)viewInstance; widget.Init(ActionName); } }
-
For being able to use this new action on a section, just add an extension method that does this:
public static IDebugAction AddInfo(this IDebugActionsSection section, string info) { InfoDebugAction debugAction = new InfoDebugAction(info); section.Add(debugAction); return debugAction; }
-
Cool! Finally, befor using the action, you just need to let the Debug Panel know that it should link the new debug action with the new widget prefab.
UDebugPanel.RegisterWidgetPrefab<InfoDebugAction>(InfoDebugActionWidgetPrefab);
-
That's it. Everything is set up for using your new debug action.
Note
You can see an example of a custom widget at the example scene DebugPanel.CustomWidgets.
Note
You can see an example of how to create custom popups on DebugPanel.CustomPopups.
When building your game for production, you may want to remove the Resources/UDebugPanel.prefab, since it won't be used. By default, Resources files are included in the build. To avoid that, we provide some functionality that can be hooked up to your build process.
UDebugPanelBuildUtils.StripFromBuild();: hides the prefab from the Unity build system.UDebugPanelBuildUtils.UnstripFromBuild();: makes the prefab visible again for Unity.
For production builds, these two methods can be used on a Build hook script, like this:
public class MyBuildHooks : IPreprocessBuildWithReport, IPostprocessBuildWithReport
{
// Called before the build starts
public void OnPreprocessBuild(BuildReport report)
{
UDebugPanelBuildUtils.StripFromBuild();
}
// Called after the build finishes
public void OnPostprocessBuild(BuildReport report)
{
UDebugPanelBuildUtils.UnstripFromBuild();
}
// Determines the order if multiple preprocessors exist
public int callbackOrder => 0;
}This ensures that the prefab is not on the build, but its ready again when the build finishes!
Note
You may need to include the DebugPanel.Editor Assembly to your assemblies.
If you found the documentation helpful and are enjoying our asset, we'd truly appreciate it if you could leave a positive rating on the Asset Store — it really helps us out ❤️.
























