dat.GUI - A lightweight graphical user interface and controller library

dat.GUI - A lightweight graphical user interface and controller library that allows you to easily manipulate variables and fire functions on the fly, inspired by the venerable dat-gui js.

TLDR;

local DatGUI = require(game.ReplicatedStorage:WaitForChild("dat.GUI"))

local obj = {
  Name = "Alex Rodin",
  Num = 1,
  Winner = true
}

local gui = DatGUI.new()

gui.add(obj, 'Name')
gui.add(obj, 'Num', 1, 50).step(1)
gui.add(obj, 'Winner')

Preview

Links

Installation

You can do the installation directly from Roblox Studio, through the Toolbox search for dat.GUI , this is the minified version of the engine (dat.GUI - Roblox).

If you want to work with the original source code (for debugging or working on improvements), access the repository at GitHub - nidorx/roblox-dat-gui

Roblox dat.GUI

Allows you to easily manipulate variables and fire functions on the fly, inspired by the venerable dat-gui.

dat.GUI magically generates a graphical user interface (sliders, color selector, etc) for each of your variables.

dat.gui’s niche is in listening to and controlling data such that it can be visualized into charts or other graphics. Creating a new DAT.GUI instance provides a new sliding pane for which to add controls to:

Use cases:

1 - To visually debug the various variables in your scripts during development
2 - To create a rich interface for your auxiliary tools (map editors, effects editors, etc.)
3 - For the construction of fast administrative interfaces

How to use

1. In your script, import the dat.GUI and instantiate it

local DatGUI = require(game.ReplicatedStorage:WaitForChild("dat.GUI"))

-- Create an instance, which also creates a UI pane
local gui = DatGUI.new();

2. With the pane ready, new controls can be added. Fields can be of type:

Boolean, BoolValue

image

local boolValue = Instance.new('BoolValue')

local BooleansObject = {
   Bool = true,
   BoolValue = boolValue
}

local guiBool  = gui.addFolder('Booleans')

guiBool.add(BooleansObject, 'Bool').listen().onChange(function(value)
   assert(BooleansObject.Bool == value)
end)

guiBool.add(BooleansObject, 'BoolValue').listen().onChange(function(value)
   assert(BooleansObject.BoolValue.Value == value)
end)

Number, NumberValue

image

Note: with a number slider available depending on options passed to it

local numberValue = Instance.new('NumberValue')
local NumbersObject = {
   Number = 25,
   NumberSlider = 0.5,
   NumberDouble = 33,
   NumberValue = numberValue,
   NumberValueSlider = numberValue
}

local guiNumbers  = gui.addFolder('Numbers')

guiNumbers.add(NumbersObject, 'Number').step(1).listen().onChange(function(value)
   assert(NumbersObject.Number == value)
end)

guiNumbers.add(NumbersObject, 'NumberSlider', 0, 1).listen().onChange(function(value)
   assert(NumbersObject.NumberSlider == value)
end)

guiNumbers.add(NumbersObject, 'NumberDouble').step(0.001).listen().onChange(function(value)
   assert(NumbersObject.NumberDouble == value)
end)

guiNumbers.add(NumbersObject, 'NumberValue').listen().onChange(function(value)
   assert(NumbersObject.NumberValue.Value == value)
end)

guiNumbers.add(NumbersObject, 'NumberValueSlider', 0, 100).listen().onChange(function(value)
   assert(NumbersObject.NumberValueSlider.Value == value)
end)

String, StringValue

image

Note: with Multiline option

local stringValue = Instance.new('StringValue')
local StringsObject = {
   String = 'Lorem ipsum dolor',
   StringValue = stringValue,
   StringMultiline = 'Lorem ipsum dolor \nLorem ipsum dolor '
}

local guiStrings  = gui.addFolder('Strings')

guiStrings.add(StringsObject, 'String').listen().onChange(function(value)
   assert(StringsObject.String == value)
end)

guiStrings.add(StringsObject, 'StringValue').listen().onChange(function(value)
   assert(StringsObject.StringValue.Value == value)
end)

guiStrings.add(StringsObject, 'StringMultiline', true).listen().onChange(function(value)
   assert(StringsObject.StringMultiline == value)
end)

Options = Enum, EnumItem, Array (Strings), Object (Key => Value string)

image

local OptionsObject = {
   OptionsEnum       = 2,
   OptionsEnumItem   = Enum.ScaleType.Slice,
   OptionsArray      = 1,
   OptionsObject     = 'THREE',
}

local guiOptions  = gui.addFolder('Options')

guiOptions.add(OptionsObject, 'OptionsEnum', Enum.ScaleType).listen().onChange(function(value, text)
   assert(OptionsObject.OptionsEnum == value)
end)

guiOptions.add(OptionsObject, 'OptionsEnumItem').listen().onChange(function(value, text)
   assert(OptionsObject.OptionsEnumItem == value)
end)

guiOptions.add(OptionsObject, 'OptionsArray', {'One', 'Two', 'Three'}).listen().onChange(function(value, text)
   assert(OptionsObject.OptionsArray == value)
end)

guiOptions.add(OptionsObject, 'OptionsObject', { ONE = 'One', TWO = 'Two', THREE = 'Three' }).listen().onChange(function(value, text)
   assert(OptionsObject.OptionsObject == value)
end)

Color3, Color3Value

image

local color3Value = Instance.new('Color3Value')
local Color3Object = {
   Color3 = Color3.fromRGB(255, 0, 255),
   Color3Value = color3Value
}

local guiColor3  = gui.addFolder('Color3')

guiColor3.add(Color3Object, 'Color3').listen().onChange(function(value)
   assert(Color3Object.Color3.R == value.R)
   assert(Color3Object.Color3.G == value.G)
   assert(Color3Object.Color3.B == value.B)
end)

guiColor3.add(Color3Object, 'Color3Value').listen().onChange(function(value)
   assert(Color3Object.Color3Value.Value.R == value.R)
   assert(Color3Object.Color3Value.Value.G == value.G)
   assert(Color3Object.Color3Value.Value.B == value.B)
end)

Vector3, Vector3Value

image

Note: with a number slider available depending on options passed to it

local vector3Value = Instance.new('Vector3Value')
local Vector3Object = {
   Vector3 = Vector3.new(10, 11, 12),
   Vector3Slider = Vector3.new(10, 11, 12),
   Vector3Value = vector3Value
}

local guiVector3  = gui.addFolder('Vector3')

guiVector3.add(Vector3Object, 'Vector3').step(1).listen().onChange(function(value)
   assert(Vector3Object.Vector3:FuzzyEq(value))
end)

 guiVector3.add(Vector3Object, 'Vector3Slider', 0, 100).listen().onChange(function(value)
   assert(Vector3Object.Vector3Slider:FuzzyEq(value))
end)

guiVector3.add(Vector3Object, 'Vector3Value', 0, 100).listen().onChange(function(value)
   assert(Vector3Object.Vector3Value.Value:FuzzyEq(value))
end)

Function, removeChild and changeName

dat_gui_function

local guiFunctions  = gui.addFolder('Functions')

local toggleVec3Controller

local Vector3Object = {
   ToggleVector3Slider = function()
      if vec3Controller ~= nil then
         guiVector3.removeChild(vec3Controller)
         vec3Controller = nil
         toggleVec3Controller.name('AddVector3Slider')
      else
         vec3Controller = guiVector3.add(Vector3Object, 'Vector3Slider', 0, 100).listen().onChange(function(value)
            assert(Vector3Object.Vector3Slider:FuzzyEq(value))
         end)
         toggleVec3Controller.name('RemoveVector3Slider')
      end
   end
}

toggleVec3Controller = guiFunctions.add(Vector3Object, 'ToggleVector3Slider')

For more details see the source code of SHOWCASE

Known issues & @TODO’s

  • ability to move the gui window around by dragging (or at least have some parameters to control where it’s placed)
  • linethrough effect should be optional (maybe another method like readonly and disabled)
  • ability to set the color of text for folders (Themes)
  • Allow adding multiple GUI (tab system maybe)
  • Allow custom controllers (Controller Factory)
  • Add CFrame controller (number & slider)

Contributing

You can contribute in many ways to this project.

Translating and documenting

I’m not a native speaker of the English language, so you may have noticed a lot of grammar errors in this documentation.

You can FORK this project and suggest improvements to this document (https://github.com/nidorx/roblox-dat-gui/edit/master/README.md).

If you find it more convenient, report a issue with the details on GitHub issues.

Reporting Issues

If you have encountered a problem with this component please file a defect on GitHub issues.

Describe as much detail as possible to get the problem reproduced and eventually corrected.

Fixing defects and adding improvements

  1. Fork it (https://github.com/nidorx/roblox-dat-gui/fork)
  2. Commit your changes (git commit -am 'Add some fooBar')
  3. Push to your master branch (git push)
  4. Create a new Pull Request

License

This code is distributed under the terms and conditions of the MIT license.

51 Likes

Nice one!
That looks a really good library!
Can you upload a copy to GitHub, so we can send PR’s etc?

1 Like

I haven’t looked in the source yet but I am wondering did you use roact to create the components, or is it created by instances?

1 Like

I am seeing how to migrate to a Rojo project (never used it). I tried rojo-rbx but it didn’t generate the GUI templates. If you know how to migrate feel free.

https://github.com/nidorx/roblox-dat-gui

1 Like

I did not use Roact only Script and ScreenGui, the project started only with a GUI to update the value of a Vector3

I made a pull request to your GitHub repository with your project in Rojo format :smiley:

Have a great day!

2 Likes

PR accepted on Github (https://github.com/nidorx/roblox-dat-gui), thank you very much @goldenstein64 for the contribution (I wouldn’t know how to convert to a Rojo project), I’m adding some test scripts to facilitate the development.

1 Like

Thanks to @aaron_mccoy for the feedback, I added it on the roadmap, with the conversion to the Rojo project done by @goldenstein64 it will be possible to do a lot of cool things in this project. :smile:

1 Like

Hey! A few questions, are you supposed to assign to a frame, gui object of some sort, and if so how.
If not, then does it create a frame, and is there any way to control the position of it inside the script. Other than that I can see myself using this in the near future, really nice plugin keep it up!

I intend to make it more dynamic, allowing it to be used within other elements for example (and from external information such as height and width, internally manage the behavior [scroll, etc.]).

But I confess that it is not my main focus at the moment (I am focused on a game I am developing).

But an important detail, the source code is available on Github, take a look there, very easy to test with Rojo.

Update v1.1

  • Fixed several bugs
  • Removal of duplicate codes
  • Various code improvements

The code in its current state is ready to receive the expected evolutions, among them:

  • Allow themes
  • Resizing
  • Individual panels
  • Inject in external panels
  • Allow custom controllers
2 Likes

Update v1.2

  • Added support for StringValue, NumberValue, Vector3Value, Color3Value, BoolValue
  • Correction in the removeChild method
  • Added Multiline String
1 Like

Update v1.2.2

  • Fixed initialization of numbers (Min, Max, Value)

This. Is. Amazing. I just made a gui library right now - and oh my god - yours is so much better.
I kinda regret making the library now.

1 Like

Another thing, why is the module obfuscated? I don’t want some backdoor in my game.

It is minified for ease of use (copying just one file is easier to work with). There is no backdoor, The source code is available on Github, you can generate the minified version itself if you want, or even use it without the minification (you only have to copy more files, as it is modularized).

If you want to work with the original source code, access the repository at GitHub - nidorx/roblox-dat-gui

1 Like

I’m working on some improvements (because I use it to make my tools).

Among the improvements in progress are: Correction of Color and Options (sometimes it is getting stuck), allowing to add custom components, controllers for drawing/plot (Lines, Curves, etc.)

2 Likes

BIG Update v1.2.3

  • Allows custom controllers gui.addCustom (name, {Frame, Color, OnRemove, Height})
    dat_gui_custom
  • Added the controller.help (text) method
    dat_gui_help
  • Added the gui.addLogo (assetId, height) method
    image
  • Allows you to pin folders
    dat_gui_pin
  • Allows to Move (Panels stick when being moved)
    dat_gui_move
  • Allows resizing
    dat_gui_resize
  • Allows you to close
    dat_gui_close
  • Bug fixes in OptionController and ColorController
  • Improved Scroll (works with Drag)
  • Compatibility with touch devices (Mobile, Tablet)
  • Visual and event capture improvements
2 Likes

This looks very cool!
Is this supported on mobile? The example place only works on pc.