Introduction
This tutorial will show you how to create a dock widget plugin, with the studio themes and general UI style of roblox studio. Since this is mainly focusing on the UI part we will just make our plugin weld the selected parts. I reccomend using a designated place for plugin development to insure we dont destroy one of our games.
Organization
For organization we will be using a module for creating the ui, and binding to studio color changes and such. We will have a welding module too, and a main script to put it all together.
Assets
The only real asset required is this API.
Scripting
Create a localscript in StarterGui.
To begin we will make the widget. We will use plugin:CreateDockWidgetPluginGui(suffix, widgetInfo)
to create the plugin. We will then name the widget. So lets review our code so far:
--[[
CREATING THE WIDGET
]]
local widgetInfo = DockWidgetPluginGuiInfo.new(Enum.InitialDockState.Float, --This can be changed--
false,
false,
200,
200,
150,
150)
local widget = plugin:CreateDockWidgetPluginGui("Weld Plugin", widgetInfo)
widget.Title = "Weld Plugin"
To download the plugin, right click on your localscript, press Save As Local Plugin
, then rename your plugin and save it.
As you can see nothing happens. Thats because the widget isn’t enabled. So lets do that. Create a toolbar, create a button on that toolbar. Toggle the widget when the buttton is pressed. So lets update our script to:
--[[
CREATING THE WIDGET
]]
local widgetInfo = DockWidgetPluginGuiInfo.new(Enum.InitialDockState.Float, --This can be changed--
false,
false,
200,
200,
150,
150)
local widget = plugin:CreateDockWidgetPluginGui("Weld Plugin", widgetInfo)
widget.Title = "Weld Plugin"
--[[
TOGGLING THE WIDGET
]]
local toolbar = plugin:CreateToolbar("Weld Plugin")
local toggle = toolbar:CreateButton("Toggle Widget", "Toggle the widget", "")
toggle.Click:Connect(function()
widget.Enabled = not widget.Enabled
end)
Now if we download our plugin again and go to Plugins on the top bar, we will Toggle Widget, press it and this should appear(will be slightly different cause im on windows 7):
You might notice its blank. So lets add a background, and a button. To do this we will use the Studio Widgets, mentioned in the assets sectioned. To load we will use a modified section of code from the API. We just change it so the folder isnt in the workspace and rename it to “WidgetAddOns”. Make a new module script called “AddOns” parented to the local script. Paste this before local module = {}
--[[
LOADING THE WIDGET ADD ONS
]]
local http = game:GetService("HttpService")
local req = http:GetAsync("https://api.github.com/repos/Roblox/StudioWidgets/contents/src")
local json = http:JSONDecode(req)
local WidgetAddOns = Instance.new("Folder")
WidgetAddOns.Name = "StudioWidgets"
for i = 1, #json do
local file = json[i]
if (file.type == "file") then
local name = file.name:sub(1, #file.name-4)
local module = Instance.new("ModuleScript")
module.Name = name
module.Source = http:GetAsync(file.download_url)
module.Parent = WidgetAddOns
end
end
Now lets add a function to generate the gui buttons. We will create a background and sync its color using the gui utilities then make a button. So lets review our code.
--[[
LOADING THE WIDGET ADD ONS
]]
local http = game:GetService("HttpService")
local req = http:GetAsync("https://api.github.com/repos/Roblox/StudioWidgets/contents/src")
local json = http:JSONDecode(req)
local WidgetAddOns = Instance.new("Folder")
WidgetAddOns.Name = "StudioWidgets"
for i = 1, #json do
local file = json[i]
if (file.type == "file") then
local name = file.name:sub(1, #file.name-4)
local module = Instance.new("ModuleScript")
module.Name = name
module.Source = http:GetAsync(file.download_url)
module.Parent = WidgetAddOns
end
end
local module = {}
function module:GenerateButtons(widget)
local bgframe = Instance.new("Frame")
bgframe.Parent = widget
bgframe.Size = UDim2.new(1,0,1,0)
require(WidgetAddOns.GuiUtilities).syncGuiElementBackgroundColor(bgframe)
local button = require(WidgetAddOns.CustomTextButton).new("Weld", "Weld Objects")
local buttonObject = button:GetButton()
buttonObject.Size = UDim2.new(0,200,0,50)
buttonObject.TextLabel.TextColor3 = Color3.new(1,1,1)
buttonObject.Parent = bgframe
buttonObject.Position = UDim2.new(0.5,-100,0.5,-25)
end
return module
Now just require the script and add the buttons. Add this to the end:
--[[
BUTTONS
]]
local AddOns = require(script.AddOns):GenerateButtons(widget)
Now finnally lets do the function.
widget.Frame.Weld.MouseButton1Down:Connect(function()
local selection = game:GetService("Selection"):Get()
if selection then
if #selection > 0 then
local last = selection[1]
for _,v in pairs(selection) do
if (v:IsA("BasePart")) then
if (last) then
local w = Instance.new("Weld")
w.Name = ("%s_Weld"):format(v.Name)
w.Part0,w.Part1 = last,v
w.C0 = last.CFrame:inverse()
w.C1 = v.CFrame:inverse()
w.Parent = last
end
last = v
end
end
end
end
end)
So our final script should look like this:
--[[
CREATING THE WIDGET
]]
local widgetInfo = DockWidgetPluginGuiInfo.new(Enum.InitialDockState.Float, --This can be changed--
false,
false,
200,
200,
150,
150)
local widget = plugin:CreateDockWidgetPluginGui("Weld Plugin", widgetInfo)
widget.Title = "Weld Plugin"
--[[
TOGGLING THE WIDGET
]]
local toolbar = plugin:CreateToolbar("Weld Plugin")
local toggle = toolbar:CreateButton("Toggle Widget", "Toggle the widget", "")
toggle.Click:Connect(function()
widget.Enabled = not widget.Enabled
end)
--[[
BUTTONS
]]
local AddOns = require(script.AddOns):GenerateButtons(widget)
widget.Frame.Weld.MouseButton1Down:Connect(function()
local selection = game:GetService("Selection"):Get()
if selection then
if #selection > 0 then
local last = selection[1]
for _,v in pairs(selection) do
if (v:IsA("BasePart")) then
if (last) then
local w = Instance.new("Weld")
w.Name = ("%s_Weld"):format(v.Name)
w.Part0,w.Part1 = last,v
w.C0 = last.CFrame:inverse()
w.C1 = v.CFrame:inverse()
w.Parent = last
end
last = v
end
end
end
end
end)
And the module:
--[[
LOADING THE WIDGET ADD ONS
]]
local http = game:GetService("HttpService")
local req = http:GetAsync("https://api.github.com/repos/Roblox/StudioWidgets/contents/src")
local json = http:JSONDecode(req)
local WidgetAddOns = Instance.new("Folder")
WidgetAddOns.Name = "StudioWidgets"
for i = 1, #json do
local file = json[i]
if (file.type == "file") then
local name = file.name:sub(1, #file.name-4)
local module = Instance.new("ModuleScript")
module.Name = name
module.Source = http:GetAsync(file.download_url)
module.Parent = WidgetAddOns
end
end
local module = {}
function module:GenerateButtons(widget)
local bgframe = Instance.new("Frame")
bgframe.Parent = widget
bgframe.Size = UDim2.new(1,0,1,0)
require(WidgetAddOns.GuiUtilities).syncGuiElementBackgroundColor(bgframe)
local button = require(WidgetAddOns.CustomTextButton).new("Weld", "Weld Objects")
local buttonObject = button:GetButton()
buttonObject.Size = UDim2.new(0,200,0,50)
buttonObject.TextLabel.TextColor3 = Color3.new(1,1,1)
buttonObject.Parent = bgframe
buttonObject.Position = UDim2.new(0.5,-100,0.5,-25)
end
return module
Now for downloading the plugin, we have to select the local script & the module inside it, then save as local plugin. When you toggle the widget, you should see this!
Now if you select two parts and you click weld objects you will see a weld gets created beetween the two parts. This will also work with more than 2 parts.
Conclusion
So know you know how to make a dock widget plugin. If you look at the Studio Widgets API, there should be more information about other types of ui.
This is my first community tutorial so please give me feedback!