If you are using Knit then this thread will assume you already know the basics of using Knit, if you don’t know how to use Knit the steps should be mostly similar to either way. I have also added how to create this without Knit
What is a Prompt
If you have played many of the front page games, you will almost always see a similar system in place which allows for a prompt to appear for a player. A prompt system is used for confirming player actions and can help resolve issues where players might have clicked on an action accidentally. A player should almost never have to deal with issues where they accidentally click on a button, and it ends up making a player lose some of their currency, or making them buy something they didn't want. This is why buying items in-game brings up a prompt to confirm your action in Roblox.This can also save you from some people expecting refunds after buying an item accidentally
Setting up the Template
Before we get into the scripting required for this system, we need to have a template ready for the prompt. I have created this basic Prompt GUI which I will be using for this tutorial (I know it looks ugly, I am not an artistic person)Make sure the background transparency for the Body, Title and Buttons are set to 1 (I kept it at 0.5 to show the size and position they are at
The Template you make does not have to look like this, you could create one that is entirely different. Your Text Labels and Frames don’t need to have the same names either. if you decide to change the names then the only things you will have to change are the names in the code to the name that represents those instances.
After we have created the template, we will need buttons to represent our two choices (usually those choices are accept/deny. Of course the Text for these buttons will be changed when we actually create the prompt!
Our Template is almost done, now we just have to parent them in the places where we can use them with ease. For my case, I have created a Controller under Replicated Storage and parented the
two buttons and the Prompt GUI separately under the Controller
Creating the Controller
The template is complete and ready to be scripted!
Before we begin our coding, we should plan out how we want our script to work, this is a great idea for small and large-scale tasks, and in this case it should be relatively easy! here are the things we need the prompt system to accomplish.
- Prompt is created through a module using
Prompt:Create(parameters)
- The parameters indicate most of what will be done to that prompt (such as the title, body, and if we want an accept button, or deny button, or both, and the text that should be in those buttons, and what should happen when we click those buttons)
- Setup connection to the buttons created by our parameters (#2)
- Whenever the buttons are clicked, we disconnect the events, run our callback, and then destroy the Prompt
Now that we have our Prompt planned out, we can begin to work on it (I can tell some people are saying “Finally!”)
Since we want to use a Knit Controller and our Controller’s purpose is to create Prompts, we might aswell name our controller Prompt Controller. Here’s what this looks like
-- SERVICES --
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- VARIABLES --
local Player = Players.LocalPlayer -- For Player.PlayerGui
-- MODULES --
local Knit = require(ReplicatedStorage.Knit)
-- KNIT CONTROLLER --
local PromptController = Knit.CreateController {
Name = "PromptController";
}
return PromptController
if you are not using Knit, you can get rid of the parts with Knit and set PromptController to table directly
local PromptController = {}
as we stated earlier, we want to create a prompt using Prompt:Create(settings)
and we can do that by adding a method to the Controller or if you aren’t using Knit you can just add a method to the PromptController table
function PromptController:Create(settingsTbl) -- The layout for this table will be explained
end
Now we can create a Prompt simply by doing:
local PromptController = Knit.Controllers.PromptController
PromptController:Create(SettingsTbl)
or If you aren’t using Knit you can just do
function PromptController:Create(settingsTbl) -- The layout for this table will be explained
end
PromptController:Create(settingsTbl)
in our planning (#2) we stated that most of our prompt, such as the Text Labels, and Buttons will be controlled by the SettingsTbl provided to the PromptController:Create(SettingsTbl)
and because of this we must keep a watch on our layout for this table. For this system it’s really easy, here is a template of our SettingsTbl and how it should look:
{
Title = "", -- This will be the title of our prompt
Body = "", -- This will be the body of our prompt
-- V These are optional V --
AcceptButton = { -- This table will allow us to create an AcceptButton
Text = "", -- This will be the Text of the AcceptButton
Callback = function() -- This function will run when the player clicks the AcceptButton
end,
},
DenyButton = { -- This table will allow us to create an DenyButton
Text = "", -- This will be the Text of the DenyButton
Callback = function() -- This function will run when the player clicks the DenyButton
end,
},
}
Now that we have the layout of our SettingsTbl, we can create our prompt based on that. But before we jump to that, we must indicate where our PromptGUI and the AcceptButton and DenyButton are. Remember that we parented them to our current module so we can get them all through using script
-- VARIABLES --
local PromptGUI = script.PromptGUI
local AcceptButton = script.AcceptButton
local DenyButton = script.DenyButton
Now that we have our variables set in place, we can begin on our :Create()
method. Since our Title and Body and both mandatory while the AcceptButton and DenyButton are optional, we must check if the Title and Body exist, if not then we will error. To do this we can simply add an assert()
function PromptController:Create(settingsTbl)
assert(settingsTbl.Title, "Prompt Title not found") -- This will cause an error if the Title is not found
assert(settingsTbl.Body, "Prompt Body not found") -- This will cause an error if the Body is not found
local Prompt = PromptGUI:Clone() -- Clone our GUI so we can use it multiple times
local PromptFrame = Prompt.UI_Prompt
local ButtonHolder = PromptFrame.Buttons
PromptFrame.Title.Text = settingsTbl.Title -- This will change the Text for the Title
PromptFrame.Body.Text = settingsTbl.Body -- This will change the Text for the Body
Prompt.Parent = Player.PlayerGui
end
We have completed our basic prompt and since we want to test this, we can use the :KnitStart()
method provided by Knit to test it easily without having to go in a different script.
function PromptController:KnitStart()
self:Create({
Title = "TestTitle",
Body = "TestBody"
})
end
If you are not using Knit then you can just do
function PromptController:Create(settingsTbl)
assert(settingsTbl.Title, "Prompt Title not found") -- This will cause an error if the Title is not found
assert(settingsTbl.Body, "Prompt Body not found") -- This will cause an error if the Body is not found
local Prompt = PromptGUI:Clone() -- Clone our GUI so we can use it multiple times
local PromptFrame = Prompt.UI_Prompt
local ButtonHolder = PromptFrame.Buttons
PromptFrame.Title.Text = settingsTbl.Title -- This will change the Text for the Title
PromptFrame.Body.Text = settingsTbl.Body -- This will change the Text for the Body
Prompt.Parent = Player.PlayerGui
end
PromptController:Create({
Title = "TestTitle",
Body = "TestBody"
})
You will notice that when you join the game, it should create a prompt and set the Title and Body Text Label’s text property to the ones we provided in the SettingsTbl (in this case “TestTitle” and “TestBody”) But your probably wondering (???) where are the buttons?? well… let’s add them. We have to add them based on our SettingsTbl which should be pretty easy. All we have to do is check if the AcceptButton
or DenyButton
tables exist in our SettingsTbl
PromptFrame.Title.Text = settingsTbl.Title -- This will change the Text for the Title
PromptFrame.Body.Text = settingsTbl.Body -- This will change the Text for the Body
local AcceptSettings = settingsTbl.AcceptButton
local DenySettings = settingsTbl.DenyButton
if AcceptSettings then
-- This code will run only if settingsTbl.AcceptButton exists
end
if DenySettings then
-- This code will run only if settingsTbl.AcceptButton exists
end
for some micro optimization (because why not) I decided to create a function to create the button we need
local function CreateButton(BtnType, BtnText, Callback)
local Button = BtnType:Clone() -- Clones the ButtonType passed to it
Button.Parent = ButtonHolder -- The Button is now in our ButtonFrame
Button:FirstChildWhichIsA("TextLabel").Text = BtnText -- Set the TextLabel's Text Property in our Button
Button.MouseButton1Click:Connect(function() -- Detects when our Button is Clicked
if Callback then -- Make sure our callback exists, because we might want to create a deny button to cancel the action
Callback() -- call the callback function
end
Prompt:Destroy() -- This will delete our connections set to the buttons as well as clean up the PromptGUI
end)
end
Now our Buttons can be created with ease, and all we have to do is pass the buttons to the CreateButton function if the button settings exist
local function CreateButton(BtnType, BtnText, Callback)
local Button = BtnType:Clone()
Button.Parent = ButtonHolder
Button.Text = BtnText
Button.MouseButton1Click:Connect(function()
if Callback then
Callback()
end
Prompt:Destroy() -- This will delete our connections set to the buttons as well as clean up the PromptGUI
end)
end
if AcceptSettings then
assert(AcceptSettings.Text, "Text for AcceptButton not found") -- Will Error if Text for AcceptButton does not exist
CreateButton(AcceptButton, AcceptSettings.Text, AcceptSettings.Callback)
end
if DenySettings then
assert(DenySettings.Text, "Text for DenyButton not found") -- Will Error if Text for DenyButton does not exist
CreateButton(DenyButton, DenySettings.Text, DenySettings.Callback)
end
Now if we run our code in the same way we did above but pass it these settings instead
function PromptController:KnitStart()
local settingsTbl = {
Title = "TestTitle", -- This will set the text for the title
Body = "TestBody", -- This will set the text for the body
AcceptButton = { -- This will create the AcceptButton
Text = "AcceptTest", -- This will set the text for the AcceptButton
Callback = function() -- This will run when we call "AcceptSettings.Callback()"
print("Accept Button was clicked")
end,
},
DenyButton = { -- This will create the DenyButton
Text = "DenyTest", -- This will set the text for the DenyButton
Callback = function() -- This will run when we call "DenySettings.Callback()"
print("Deny Button was clicked")
end,
}
}
self:Create(settingsTbl)
end
or if you are not using Knit, you can do pass the settingsTbl above to PromptController:Create(settingsTbl)
Now if we run our game and test out our Prompt System you will see that it works exactly as we want
Completed
The Prompt System is complete and it works the way we envisioned it to work! Of course the rest of the System is mostly personal preference, as that’s where most of the creativity comes in!
I have made this uncopylocked and you can check it out here
Whole Script w/ Knit
-- SERVICES --
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- VARIABLES --
local PromptGUI = script.PromptGUI
local AcceptButton = script.AcceptButton
local DenyButton = script.DenyButton
local Player = Players.LocalPlayer
-- MODULES --
local Knit = require(ReplicatedStorage.Knit)
-- KNIT CONTROLLER --
local PromptController = Knit.CreateController {
Name = "PromptController";
}
--[[
local SettingsTbl = {
Title = "", -- This will be the title of our prompt
Body = "", -- This will be the body of our prompt
-- V These are optional V --
AcceptButton = { -- This table will allow us to create an AcceptButton
Text = "", -- This will be the Text of the AcceptButton
Callback = function() -- This function will run when the player clicks the AcceptButton
end,
},
DenyButton = { -- This table will allow us to create an DenyButton
Text = "", -- This will be the Text of the DenyButton
Callback = function() -- This function will run when the player clicks the DenyButton
end,
},
}
]]--
function PromptController:Create(settingsTbl)
assert(settingsTbl.Title, "Prompt Title not found") -- This will cause an error if the Title is not found
assert(settingsTbl.Body, "Prompt Body not found") -- This will cause an error if the Body is not found
local Prompt = PromptGUI:Clone() -- Clone our GUI so we can use it multiple times
local PromptFrame = Prompt.UI_Prompt
local ButtonHolder = PromptFrame.Buttons
PromptFrame.Title.Text = settingsTbl.Title -- This will change the Text for the Title
PromptFrame.Body.Text = settingsTbl.Body -- This will change the Text for the Body
local AcceptSettings = settingsTbl.AcceptButton
local DenySettings = settingsTbl.DenyButton
local function CreateButton(BtnType, BtnText, Callback)
local Button = BtnType:Clone()
Button.Parent = ButtonHolder
Button.Text = BtnText
Button.MouseButton1Click:Connect(function()
if Callback then
Callback()
end
Prompt:Destroy() -- This will delete our connections set to the buttons as well as clean up the PromptGUI
end)
end
if AcceptSettings then
assert(AcceptSettings.Text, "Text for AcceptButton not found")
CreateButton(AcceptButton, AcceptSettings.Text, AcceptSettings.Callback)
end
if DenySettings then
assert(DenySettings.Text, "Text for DenyButton not found")
CreateButton(DenyButton, DenySettings.Text, DenySettings.Callback)
end
Prompt.Parent = Player.PlayerGui
end
function PromptController:KnitStart()
self:Create({
Title = "Knit Test",
Body = "This Prompt is made via Knit",
AcceptButton = {
Text = "AcceptTest",
Callback = function()
print("Accept Button was clicked")
end,
},
DenyButton = {
Text = "DenyTest",
Callback = function()
print("Deny Button was clicked")
end,
}
})
end
return PromptController
Whole Script w/o Knit
-- SERVICES --
local Players = game:GetService("Players")
-- VARIABLES --
local PromptGUI = script.PromptGUI
local AcceptButton = script.AcceptButton
local DenyButton = script.DenyButton
local Player = Players.LocalPlayer
-- CONTROLLER --
local PromptController = {}
--[[
local SettingsTbl = {
Title = "", -- This will be the title of our prompt
Body = "", -- This will be the body of our prompt
-- V These are optional V --
AcceptButton = { -- This table will allow us to create an AcceptButton
Text = "", -- This will be the Text of the AcceptButton
Callback = function() -- This function will run when the player clicks the AcceptButton
end,
},
DenyButton = { -- This table will allow us to create an DenyButton
Text = "", -- This will be the Text of the DenyButton
Callback = function() -- This function will run when the player clicks the DenyButton
end,
},
}
]]--
function PromptController:Create(settingsTbl)
assert(settingsTbl.Title, "Prompt Title not found") -- This will cause an error if the Title is not found
assert(settingsTbl.Body, "Prompt Body not found") -- This will cause an error if the Body is not found
local Prompt = PromptGUI:Clone() -- Clone our GUI so we can use it multiple times
local PromptFrame = Prompt.UI_Prompt
local ButtonHolder = PromptFrame.Buttons
PromptFrame.Title.Text = settingsTbl.Title -- This will change the Text for the Title
PromptFrame.Body.Text = settingsTbl.Body -- This will change the Text for the Body
local AcceptSettings = settingsTbl.AcceptButton
local DenySettings = settingsTbl.DenyButton
local function CreateButton(BtnType, BtnText, Callback)
local Button = BtnType:Clone()
Button.Parent = ButtonHolder
Button.Text = BtnText
Button.MouseButton1Click:Connect(function()
if Callback then
Callback()
end
Prompt:Destroy() -- This will delete our connections set to the buttons as well as clean up the PromptGUI
end)
end
if AcceptSettings then
assert(AcceptSettings.Text, "Text for AcceptButton not found")
CreateButton(AcceptButton, AcceptSettings.Text, AcceptSettings.Callback)
end
if DenySettings then
assert(DenySettings.Text, "Text for DenyButton not found")
CreateButton(DenyButton, DenySettings.Text, DenySettings.Callback)
end
Prompt.Parent = Player.PlayerGui
end
PromptController:Create({
Title = "Test",
Body = "This Prompt is not made via Knit",
AcceptButton = {
Text = "AcceptTest",
Callback = function()
print("Accept Button was clicked")
end,
},
DenyButton = {
Text = "DenyTest",
Callback = function()
print("Deny Button was clicked")
end,
}
})
return PromptController
- Yes
- No
0 voters