Skip to content

warkenji/GDebugPanelGodot

Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

43 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

License: MIT Contributions welcome Release Twitter Follow

LogoWide

GDebugPanel-Godot is a lightweight and versatile ingame debug panel for Godot 4.x 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 debug panel with options in your Godot 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 allwing for the creation of new ones, with ease.

OptionsArt

🍰 Features

  • Simple API: GDebugPanel-Godot provides an intuitive and easy-to-use API with C#.

    GDebugPanel.Show(Control);
    GDebugPanel.Hide();
    
    IDebugActionsSection section = GDebugPanel.AddSection("Section name");
    section.AddButton("Button name", () => GD.Print("Button 2"));
    section.AddInt("Int selector name", val => _int = val, () => _int);
  • Adaptative: The different widgets support and adapt to different screen aspect ratios, making it a good fit for both, desktop and mobile.

    AdaptativeArt

  • 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.

    AutomaticArt

  • Organization: Organize your options using collapsable sections.

    Gif2

  • Fuzzy search: Quicly find the options you were looking for with the search bar!

    Gif

  • 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 affect to the preformance of your game.

πŸ“¦ Installation

Form Asset Library

  1. Inside Godot, open the AssetLib tab.

image

  1. Search for and select "GDebugPanel (C#)".

image

  1. Download then install the asset.

From releases:

  1. Download the latest GDebugPanelGodot.zip release.
  2. Unpack the GDebugPanelGodot.zip folder into the Godot's root folder. Make sure the GDebugPanelGodot is inside the addons/ folder.

βœ”οΈ After installing

To quickly check if everything has been setup properly, you can go to GDebugPanelGodot/Examples/Scenes/ and open any of the example scenes. When you run any of those scenes, a simple functionality example should play.

Warning

It's very important that the asset is placed under the addons/ folder. Not doing so will make the asset not work.

Note

This asset is not setup as a plugin. Just adding it to your project will make it work.

πŸ“š Getting started

Showing / Hiding

  • For showing the panel, you just need to call the Show method, providing as a parameter the Control where you want the panel to be placed at.
    GDebugPanel.Show(Control);
  • For hiding the panel, just call the Hide method.
    GDebugPanel.Hide();

Sections

Debug options are divided within different sections. These sections allow you to better organize your options. You cannot create a debug option outside of a section.

  • Creating a new section is very simple, you just need to call AddSection and provide a section name:
    IDebugActionsSection section = GDebugPanel.AddSection("Section name");
  • Removing a section is equally as simple. Just call RemoveSection, and provide the section you want to remove.
    GDebugPanel.RemoveSection(section);

Sections can be both, collapsable and non collapsable. You can decide which one you want by calling:

  • AddSection for a collapsable one.
    IDebugActionsSection section = GDebugPanel.AddSection("Section name");
  • AddNonCollapsableSection for a non collapsable one.
    IDebugActionsSection section = GDebugPanel.AddNonCollapsableSection("Section name");

Automatic debug options

This asset has the ability of scanning for properties and methods in C# classes, to automatically create de adecuate widgets.

One of such classes may look like this:

public sealed class ExampleOptionsObject
{
    public enum ExampleEnum
    {
        Enum1,
        Enum2,
        Enum3,
        SomeLongValueThat,
    }
    
    public void ButtonExample() => GD.Print("Button Option!");
    public bool ToggleExample { get; set; }
    public string DynamicInfoExample { get; set; } = "Dynamic Info";
    public string InfoExample => "Info";
    public Color ColorExample { get; set; }
    public string StringExample { get; set; }
    public int IntExample { get; set; }
    public float FloatExample { get; set; }
    public ExampleEnum EnumExample { get; set; }
}

Then we add the class like this:

GDebugPanel.AddSection("Section name", new ExampleOptionsObject());

And we will get debug options like this:

Reflection

Manual debug options

This is the most part of this assets, the debug options (or widgets). Once you have a section instance, you have some debug options avaliable:

  • 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");
  • Button: a simple button with a name.
    section.AddButton("Button name", () => GD.Print("Pressed"));
  • 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);
  • Color: a color selector with a name. Requests a setter and a getter for the value.
    string someColor = Colors.White;
    section.AddColor("Color name", val => someColor = val, () => someColor);
  • String: a string editor with a name. Requests a setter and a getter for the value.
    string someString = "String value";
    section.AddString("String name", val => someString = val, () => someString);
  • Int: an int selector with a name. Requests a setter and a getter for the value.
    int someInt = 0;
    section.AddInt("Int name", val => someInt = val, () => someInt);
  • Float: an float selector with a name. Requests a setter and a getter for the value.
    float someFloat = 0f;
    section.AddFloat("Float name", val => someFloat = val, () => someFloat);
  • Enum: an enum selector with a name. Requests a setter and a getter for the value.
    public enum ExampleEnum
    {
        Enum1,
        Enum2,
        Enum3,
    }
    ExampleEnum someEnum = default;
    section.AddEnum("Enum name" val => someEnum = val, () => someEnum);

Creating more debug options

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 Int widget as an example.

  1. The first thing you need to do is create a new class and inherit from IDebugAction. This interface will force you to implement DebugActionWidget InstantiateWidget(DebugPanelView debugPanelView) method, which is responsable for instantiating the widget on the Ui. We will not implement it for now.

    public sealed class IntDebugAction : IDebugAction
    {    
        public IntDebugAction()
        {
        }
    
        public DebugActionWidget InstantiateWidget(DebugPanelView debugPanelView)
        {
            throw new NotImplementedException();
        }
    }
  2. Next, we need a new DebugActionWidget, which will be the actual Node placed on the Ui. Since the widget is made of a label and a spin box, we will add references to it. LabelAutowrapSelectionByControlWidthController is an utility class that helps wrap text when it cannot fit its designated width.

    public partial class IntDebugActionWidget : DebugActionWidget
    {
        [Export] public LabelAutowrapSelectionByControlWidthController? LabelAutowrapController;
        [Export] public Label? Label;
        [Export] public SpinBox? SpinBox;
    }
  3. Going back to the IntDebugAction class, we need to implement InstantiateWidget, by instantiating the created IntDebugActionWidget. For this, you will need to create the requiered Ui PackedScene, add the IntDebugActionWidget script to it, and reference this PackedScene on your IntDebugAction in any prefered way. In the case of internal widgets, they are references on the main debug panel.

    public sealed class IntDebugAction : IDebugAction
    {    
        public IntDebugAction()
        {
        }
    
        public DebugActionWidget InstantiateWidget(DebugPanelView debugPanelView)
        {
            // IntDebugActionWidget is a PackedScene
            IntDebugActionWidget widget = debugPanelView.IntDebugActionWidget!.Instantiate<IntDebugActionWidget>();
            return widget;
        }
    }
  4. For being able to use this new action on a section, just add an extension method that does that:

    public static IDebugAction AddInt(this IDebugActionsSection section)
    {
        IDebugAction debugAction = new IntDebugAction();
        section.Add(debugAction);
        return debugAction;
    }
  5. Cool! If all went well, you should now be able to see your widget on the debug panel once you call your Add method. Now we just need to add functionality to it. We first add all the necessary parameters to our action. In this case, the name of the option, and a getter and a setter that will be called by our widget.

     public sealed class IntDebugAction : IDebugAction
     {
         public string Name { get; }
         public Action<int> SetAction { get; }
         public Func<int> GetAction { get; }
     
         public IntDebugAction(string name, Action<int> setAction, Func<int> getAction)
         {
             Name = name;
             SetAction = setAction;
             GetAction = getAction;
         }
     
         public DebugActionWidget InstantiateWidget(DebugPanelView debugPanelView)
         {
             IntDebugActionWidget widget = debugPanelView.IntDebugActionWidget!.Instantiate<IntDebugActionWidget>();
             widget.Init(debugPanelView.ContentControl!, Name, SetAction, GetAction);
             return widget;
         }
     }
    public partial class IntDebugActionWidget : DebugActionWidget
    {
        [Export] public LabelAutowrapSelectionByControlWidthController? LabelAutowrapController;
        [Export] public Label? Label;
        [Export] public SpinBox? SpinBox;
    
        Action<int>? _setAction;
        Func<int>? _getAction;
    
        public void Init(Control sizeControl, string name, Action<int> setAction, Func<int> getAction)
        {
            LabelAutowrapController!.SizeControl = sizeControl;
            _setAction = setAction;
            _getAction = getAction;
        
            Label!.Text = name;
            SpinBox.MinValue = int.MinValue;
            SpinBox.MaxValue = int.MaxValue;
            SpinBox.Value = getAction.Invoke();
            SpinBox.ConnectSpinBoxValueChanged(Changed);
        }
    
        public override bool Focus()
        {
            SpinBox!.GrabFocus();
            return true;
        }
    
        void Changed(float value)
        {
            int truncatedValue = (int)value;
            _setAction!.Invoke(truncatedValue);
            truncatedValue = _getAction!.Invoke();
            SpinBox!.SetValueNoSignal(truncatedValue);
        }
    }

About

Runtime debug panel for Godot 4.x with C#

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C# 100.0%