-- openStudio Popup Parts
-- Local Popup Handler
-- Build 3.5 Multiple Texts 20/4/25
-- // CONFIG
-- i️i️ Watch the tutorial by @bookedsam for help configuring the system. i️i️
local config = { -- Change these settings how you like. Settings are case sensitive.
-- The name of the theme. Included themes:
-- "Classic light" "Classic dark" "Bubbly" "Code" "Modern" "Transparent"
["Theme"] = "Classic light",
-- The type of animation. Included animations:
-- "Fade" "Typewriter" "Bounce"
["Animation"] = "Typewriter",
-- Set to false if you want it to only work once.
["Repeat"] = true
}
-- ⚠️⚠️ ONLY EDIT BEYOND THIS POINT IF YOU KNOW WHAT YOU ARE DOING ⚠️⚠️
-- // VARIABLES
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")
local Players = game:GetService("Players")
local themes = ReplicatedStorage:WaitForChild("openPopup")
local partFolder = workspace:WaitForChild("openPopup")
local label = nil
local labelSave = nil
local animations = {}
-- // FUNCTIONS
-- Animation that fades in and out the text.
animations.Fade = function(text: string)
local info = TweenInfo.new(1)
local fadeIn = TweenService:Create(label, info,
{BackgroundTransparency = labelSave.BackgroundTransparency,
TextTransparency = labelSave.TextTransparency})
local fadeOut = TweenService:Create(label, info,
{BackgroundTransparency = 1,
TextTransparency = 1})
label.Transparency = 1
fadeIn:Play()
fadeIn.Completed:Wait()
task.wait(string.len(text) / 20)
fadeOut:Play()
fadeOut.Completed:Wait()
end
-- Animation that has a typing effect.
animations.Typewriter = function(text: string)
local infoType = TweenInfo.new(string.len(text) / 10, Enum.EasingStyle.Linear)
local infoFade = TweenInfo.new(0.5)
local typeIn = TweenService:Create(label, infoType, {MaxVisibleGraphemes = string.len(text)})
local fadeIn = TweenService:Create(label, infoFade, {BackgroundTransparency = labelSave.BackgroundTransparency})
local fadeOut = TweenService:Create(label, infoFade, {BackgroundTransparency = 1, TextTransparency = 1})
label.TextTransparency = 0
label.MaxVisibleGraphemes = 0
label.BackgroundTransparency = 1
fadeIn:Play()
typeIn:Play()
typeIn.Completed:Wait()
task.wait(string.len(text) / 20)
fadeOut:Play()
fadeOut.Completed:Wait()
end
-- Animation where the text object jumps into frame.
animations.Bounce = function(text: string)
local info = TweenInfo.new(0.5, Enum.EasingStyle.Bounce, Enum.EasingDirection.Out)
local bounceIn = TweenService:Create(label, info, {Size = labelSave.Size})
local bounceOut = TweenService:Create(label, info, {Size = UDim2.new(0, 0, 0 ,0)})
label.Size = UDim2.new(0, 0, 0, 0)
bounceIn:Play()
bounceIn.Completed:Wait()
task.wait(string.len(text) / 20)
bounceOut:Play()
bounceOut.Completed:Wait()
end
local function setupPart(part)
if part:IsA("Part") then
for _, e in ipairs(part:GetChildren()) do
if e:IsA("Decal") then e:Destroy() end
end
local texts = {}
for _, v in ipairs(part:GetChildren()) do
if v:IsA("StringValue") then
texts[tonumber(v.Name)] = v.Value
end
end
local debounce = false
local connection
connection = part.Touched:Connect(function(touch)
if Players:GetPlayerFromCharacter(touch.Parent) == Players.LocalPlayer then
if debounce then return end
debounce = true
for i, v in ipairs(texts) do
label.Text = v
label.Visible = true
animations[config.Animation](v)
end
label.Visible = false
task.wait(1)
if config.Repeat then debounce = false else connection:Disconnect() end
end
end)
end
end
-- // SETUP
if not animations[config.Animation] then
warn("[openPopup] The animation you set could not be found! Defaulting to 'Fade'.")
config.Animation = "Fade"
end
if not themes:WaitForChild(config.Theme, 1) then
warn("[openPopup] The theme you set could not be found! Defaulting to 'Classic light'")
config.Theme = "Classic light"
end
label = themes:WaitForChild(config.Theme):Clone()
label.Visible = false
label.Parent = script.Parent
labelSave = themes:WaitForChild(config.Theme)
print("[openPopup] openStudio Popup System ready. Have any errors? Contact @bookedsam.")
-- // MAIN
task.wait(1)
for _, v in ipairs(partFolder:GetChildren()) do
setupPart(v)
end
partFolder.ChildAdded:Connect(function(part)
setupPart(part)
end)