
KeylessUniversal

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserInputService = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")
local player = Players.LocalPlayer
if not player then
warn("TowerHub must run as a LocalScript.")
return
end
local playerGui = player:WaitForChild("PlayerGui", 15)
if not playerGui then
warn("TowerHub: PlayerGui was not found.")
return
end
print("TowerHub: script started")
local oldGui = playerGui:FindFirstChild("TowerHub")
if oldGui then
oldGui:Destroy()
end
--==================================================
-- FIND UNIT / TOWER FOLDERS
--==================================================
local folderNames = {
tower = true,
towers = true,
unit = true,
units = true,
troop = true,
troops = true,
character = true,
characters = true,
npc = true,
npcs = true,
unitsfolder = true,
towerfolder = true,
}
local function isUnitTowerFolder(object)
return object:IsA("Folder")
and folderNames[object.Name:lower()] == true
end
local function getAllUnitsAndTowers()
local objects = {}
local seen = {}
for _, folder in ipairs(ReplicatedStorage:GetDescendants()) do
if isUnitTowerFolder(folder) then
for _, object in ipairs(folder:GetChildren()) do
if not seen[object] then
seen[object] = true
table.insert(objects, object)
end
end
end
end
table.sort(objects, function(a, b)
return a.Name:lower() < b.Name:lower()
end)
return objects
end
--==================================================
-- GUI
--==================================================
local gui = Instance.new("ScreenGui")
gui.Name = "TowerHub"
gui.ResetOnSpawn = false
gui.IgnoreGuiInset = true
gui.DisplayOrder = 999
gui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
gui.Parent = playerGui
local main = Instance.new("Frame")
main.Name = "Main"
main.AnchorPoint = Vector2.new(0.5, 0.5)
main.Position = UDim2.fromScale(0.5, 0.5)
main.Size = UDim2.fromOffset(560, 400)
main.BackgroundColor3 = Color3.fromRGB(17, 18, 24)
main.BorderSizePixel = 0
main.Visible = true
main.Parent = gui
local mainCorner = Instance.new("UICorner")
mainCorner.CornerRadius = UDim.new(0, 16)
mainCorner.Parent = main
local mainStroke = Instance.new("UIStroke")
mainStroke.Color = Color3.fromRGB(62, 65, 80)
mainStroke.Thickness = 1
mainStroke.Parent = main
--==================================================
-- RESPONSIVE SCALE
--==================================================
local uiScale = Instance.new("UIScale")
uiScale.Scale = 1
uiScale.Parent = main
local function updateScale()
local camera = workspace.CurrentCamera
if not camera then
return
end
local viewport = camera.ViewportSize
local width = viewport.X
local height = viewport.Y
local scaleX = (width - 20) / 560
local scaleY = (height - 20) / 400
local screenScale = math.min(scaleX, scaleY)
if width <= 390 then
uiScale.Scale = math.min(screenScale, 0.82)
elseif width <= 600 then
uiScale.Scale = math.min(screenScale, 0.90)
else
uiScale.Scale = math.min(screenScale, 1)
end
if uiScale.Scale <= 0 then
uiScale.Scale = 0.5
end
end
local function connectCamera()
local camera = workspace.CurrentCamera
if not camera then
return
end
camera:GetPropertyChangedSignal("ViewportSize"):Connect(updateScale)
updateScale()
end
connectCamera()
workspace:GetPropertyChangedSignal("CurrentCamera"):Connect(function()
task.defer(connectCamera)
end)
--==================================================
-- TOP BAR
--==================================================
local top = Instance.new("Frame")
top.Name = "TopBar"
top.Size = UDim2.new(1, 0, 0, 50)
top.BackgroundColor3 = Color3.fromRGB(25, 27, 35)
top.BorderSizePixel = 0
top.Parent = main
local topCorner = Instance.new("UICorner")
topCorner.CornerRadius = UDim.new(0, 16)
topCorner.Parent = top
local title = Instance.new("TextLabel")
title.BackgroundTransparency = 1
title.Position = UDim2.fromOffset(14, 0)
title.Size = UDim2.new(1, -65, 1, 0)
title.Text = "universe spawner tower"
title.TextColor3 = Color3.fromRGB(255, 255, 255)
title.TextSize = 18
title.Font = Enum.Font.GothamBold
title.TextXAlignment = Enum.TextXAlignment.Left
title.TextTruncate = Enum.TextTruncate.AtEnd
title.Parent = top
local hideButton = Instance.new("TextButton")
hideButton.Size = UDim2.fromOffset(38, 38)
hideButton.Position = UDim2.new(1, -45, 0, 6)
hideButton.BackgroundColor3 = Color3.fromRGB(47, 49, 61)
hideButton.Text = "×"
hideButton.TextColor3 = Color3.fromRGB(255, 255, 255)
hideButton.TextSize = 23
hideButton.Font = Enum.Font.GothamBold
hideButton.AutoButtonColor = false
hideButton.Parent = top
local hideCorner = Instance.new("UICorner")
hideCorner.CornerRadius = UDim.new(0, 9)
hideCorner.Parent = hideButton
--==================================================
-- LEFT PANEL
--==================================================
local left = Instance.new("Frame")
left.Name = "UnitTowerPanel"
left.Position = UDim2.fromOffset(8, 58)
left.Size = UDim2.new(0.42, -8, 1, -66)
left.BackgroundColor3 = Color3.fromRGB(24, 26, 34)
left.BorderSizePixel = 0
left.Parent = main
local leftCorner = Instance.new("UICorner")
leftCorner.CornerRadius = UDim.new(0, 12)
leftCorner.Parent = left
local listTitle = Instance.new("TextLabel")
listTitle.BackgroundTransparency = 1
listTitle.Position = UDim2.fromOffset(11, 7)
listTitle.Size = UDim2.new(1, -22, 0, 28)
listTitle.Text = "UNITS + TOWERS"
listTitle.TextColor3 = Color3.fromRGB(225, 227, 235)
listTitle.TextSize = 11
listTitle.Font = Enum.Font.GothamBold
listTitle.TextXAlignment = Enum.TextXAlignment.Left
listTitle.TextTruncate = Enum.TextTruncate.AtEnd
listTitle.Parent = left
local towerList = Instance.new("ScrollingFrame")
towerList.Name = "UnitTowerList"
towerList.Position = UDim2.fromOffset(7, 39)
towerList.Size = UDim2.new(1, -14, 1, -46)
towerList.BackgroundTransparency = 1
towerList.BorderSizePixel = 0
towerList.ScrollBarThickness = 5
towerList.ScrollBarImageColor3 = Color3.fromRGB(90, 94, 112)
towerList.ScrollBarImageTransparency = 0.15
towerList.ScrollingDirection = Enum.ScrollingDirection.Y
towerList.ScrollingEnabled = true
towerList.ElasticBehavior = Enum.ElasticBehavior.Always
towerList.AutomaticCanvasSize = Enum.AutomaticSize.Y
towerList.CanvasSize = UDim2.new(0, 0, 0, 0)
towerList.Parent = left
local towerPadding = Instance.new("UIPadding")
towerPadding.PaddingTop = UDim.new(0, 3)
towerPadding.PaddingBottom = UDim.new(0, 10)
towerPadding.PaddingLeft = UDim.new(0, 2)
towerPadding.PaddingRight = UDim.new(0, 2)
towerPadding.Parent = towerList
local towerLayout = Instance.new("UIListLayout")
towerLayout.Padding = UDim.new(0, 6)
towerLayout.HorizontalAlignment = Enum.HorizontalAlignment.Center
towerLayout.SortOrder = Enum.SortOrder.LayoutOrder
towerLayout.Parent = towerList
--==================================================
-- RIGHT PANEL
--==================================================
local right = Instance.new("Frame")
right.Name = "StatsPanel"
right.Position = UDim2.new(0.42, 4, 0, 58)
right.Size = UDim2.new(0.58, -12, 1, -66)
right.BackgroundColor3 = Color3.fromRGB(20, 21, 29)
right.BorderSizePixel = 0
right.Parent = main
local rightCorner = Instance.new("UICorner")
rightCorner.CornerRadius = UDim.new(0, 12)
rightCorner.Parent = right
local selectedTitle = Instance.new("TextLabel")
selectedTitle.BackgroundTransparency = 1
selectedTitle.Position = UDim2.fromOffset(13, 8)
selectedTitle.Size = UDim2.new(1, -26, 0, 28)
selectedTitle.Text = "SELECT A UNIT"
selectedTitle.TextColor3 = Color3.fromRGB(255, 255, 255)
selectedTitle.TextSize = 16
selectedTitle.Font = Enum.Font.GothamBold
selectedTitle.TextXAlignment = Enum.TextXAlignment.Left
selectedTitle.TextTruncate = Enum.TextTruncate.AtEnd
selectedTitle.Parent = right
local subtitle = Instance.new("TextLabel")
subtitle.BackgroundTransparency = 1
subtitle.Position = UDim2.fromOffset(14, 34)
subtitle.Size = UDim2.new(1, -28, 0, 16)
subtitle.Text = "Select an existing unit or tower"
subtitle.TextColor3 = Color3.fromRGB(125, 130, 145)
subtitle.TextSize = 9
subtitle.Font = Enum.Font.Gotham
subtitle.TextXAlignment = Enum.TextXAlignment.Left
subtitle.TextTruncate = Enum.TextTruncate.AtEnd
subtitle.Parent = right
--==================================================
-- STAT ALIASES
--==================================================
local aliases = {
Damage = {
"Damage",
"AttackDamage",
"Attack",
"DMG"
},
Range = {
"Range",
"AttackRange",
"Radius"
},
Cooldown = {
"Cooldown",
"AttackCooldown",
"FireRate",
"AttackSpeed"
},
Price = {
"Price",
"Cost",
"Cash"
},
DPS = {
"DPS",
"DamagePerSecond",
"DamagePerSec"
},
}
local function readValueObject(object)
if object:IsA("NumberValue")
or object:IsA("IntValue")
or object:IsA("StringValue")
or object:IsA("BoolValue") then
return object.Value
end
return nil
end
local function findStatInObject(object, statName)
if not object then
return nil
end
local attribute = object:GetAttribute(statName)
if attribute ~= nil then
return attribute
end
local direct = object:FindFirstChild(statName)
if direct then
local value = readValueObject(direct)
if value ~= nil then
return value
end
end
for _, alias in ipairs(aliases[statName] or {}) do
local child = object:FindFirstChild(alias)
if child then
local value = readValueObject(child)
if value ~= nil then
return value
end
end
local attr = object:GetAttribute(alias)
if attr ~= nil then
return attr
end
end
for _, descendant in ipairs(object:GetDescendants()) do
local attr = descendant:GetAttribute(statName)
if attr ~= nil then
return attr
end
local value = readValueObject(descendant)
if value ~= nil then
if descendant.Name:lower() == statName:lower() then
return value
end
for _, alias in ipairs(aliases[statName] or {}) do
if descendant.Name:lower() == alias:lower() then
return value
end
end
end
end
return nil
end
local function findStatInModule(moduleScript, statName)
if not moduleScript or not moduleScript:IsA("ModuleScript") then
return nil
end
local success, data = pcall(require, moduleScript)
if not success or type(data) ~= "table" then
return nil
end
if data[statName] ~= nil then
return data[statName]
end
for _, alias in ipairs(aliases[statName] or {}) do
if data[alias] ~= nil then
return data[alias]
end
end
for key, value in pairs(data) do
if type(key) == "string" then
if key:lower() == statName:lower() then
return value
end
for _, alias in ipairs(aliases[statName] or {}) do
if key:lower() == alias:lower() then
return value
end
end
end
end
return nil
end
local function findStat(unit, statName)
local result = findStatInObject(unit, statName)
if result ~= nil then
return result
end
for _, configName in ipairs({
"Config",
"Configuration",
"Stats",
"Data",
"TowerData",
"UnitData"
}) do
local config = unit:FindFirstChild(configName)
if config then
result = findStatInObject(config, statName)
if result ~= nil then
return result
end
end
end
for _, object in ipairs(unit:GetDescendants()) do
if object:IsA("ModuleScript") then
result = findStatInModule(object, statName)
if result ~= nil then
return result
end
end
end
return "N/A"
end
--==================================================
-- STATS
--==================================================
local statsScroll = Instance.new("ScrollingFrame")
statsScroll.Name = "StatsScroll"
statsScroll.Position = UDim2.fromOffset(7, 56)
statsScroll.Size = UDim2.new(1, -14, 1, -116)
statsScroll.BackgroundTransparency = 1
statsScroll.BorderSizePixel = 0
statsScroll.ScrollBarThickness = 5
statsScroll.ScrollBarImageColor3 = Color3.fromRGB(85, 90, 110)
statsScroll.ScrollBarImageTransparency = 0.15
statsScroll.ScrollingDirection = Enum.ScrollingDirection.Y
statsScroll.ScrollingEnabled = true
statsScroll.ElasticBehavior = Enum.ElasticBehavior.Always
statsScroll.AutomaticCanvasSize = Enum.AutomaticSize.Y
statsScroll.CanvasSize = UDim2.new(0, 0, 0, 0)
statsScroll.Parent = right
local statsPadding = Instance.new("UIPadding")
statsPadding.PaddingTop = UDim.new(0, 3)
statsPadding.PaddingBottom = UDim.new(0, 10)
statsPadding.PaddingLeft = UDim.new(0, 4)
statsPadding.PaddingRight = UDim.new(0, 4)
statsPadding.Parent = statsScroll
local statsLayout = Instance.new("UIListLayout")
statsLayout.Padding = UDim.new(0, 7)
statsLayout.HorizontalAlignment = Enum.HorizontalAlignment.Center
statsLayout.SortOrder = Enum.SortOrder.LayoutOrder
statsLayout.Parent = statsScroll
local statCards = {}
local function createStatCard(name, icon, color)
local card = Instance.new("Frame")
card.Name = name .. "Card"
card.Size = UDim2.new(1, 0, 0, 50)
card.BackgroundColor3 = Color3.fromRGB(31, 33, 43)
card.BorderSizePixel = 0
card.Parent = statsScroll
local corner = Instance.new("UICorner")
corner.CornerRadius = UDim.new(0, 9)
corner.Parent = card
local stroke = Instance.new("UIStroke")
stroke.Color = Color3.fromRGB(45, 47, 59)
stroke.Thickness = 1
stroke.Parent = card
local iconLabel = Instance.new("TextLabel")
iconLabel.Position = UDim2.fromOffset(6, 6)
iconLabel.Size = UDim2.fromOffset(38, 38)
iconLabel.BackgroundColor3 = color
iconLabel.Text = icon
iconLabel.TextColor3 = Color3.new(1, 1, 1)
iconLabel.TextSize = 17
iconLabel.Font = Enum.Font.GothamBold
iconLabel.Parent = card
local iconCorner = Instance.new("UICorner")
iconCorner.CornerRadius = UDim.new(0, 8)
iconCorner.Parent = iconLabel
local nameLabel = Instance.new("TextLabel")
nameLabel.BackgroundTransparency = 1
nameLabel.Position = UDim2.fromOffset(52, 5)
nameLabel.Size = UDim2.new(1, -62, 0, 14)
nameLabel.Text = name:upper()
nameLabel.TextColor3 = Color3.fromRGB(140, 145, 160)
nameLabel.TextSize = 8
nameLabel.Font = Enum.Font.GothamBold
nameLabel.TextXAlignment = Enum.TextXAlignment.Left
nameLabel.Parent = card
local valueLabel = Instance.new("TextLabel")
valueLabel.BackgroundTransparency = 1
valueLabel.Position = UDim2.fromOffset(52, 18)
valueLabel.Size = UDim2.new(1, -62, 0, 26)
valueLabel.Text = "--"
valueLabel.TextColor3 = Color3.fromRGB(248, 248, 252)
valueLabel.TextSize = 16
valueLabel.Font = Enum.Font.GothamBold
valueLabel.TextXAlignment = Enum.TextXAlignment.Left
valueLabel.TextTruncate = Enum.TextTruncate.AtEnd
valueLabel.Parent = card
statCards[name] = {
Card = card,
Value = valueLabel
}
end
createStatCard("Damage", "⚔", Color3.fromRGB(190, 60, 70))
createStatCard("Range", "◎", Color3.fromRGB(60, 125, 205))
createStatCard("Cooldown", "◷", Color3.fromRGB(145, 90, 205))
createStatCard("Price", "$", Color3.fromRGB(50, 165, 95))
createStatCard("DPS", "⚡", Color3.fromRGB(220, 150, 45))
--==================================================
-- SELECTION
--==================================================
local selectedUnit = nil
local selectedUnitName = nil
local towerButtons = {}
local function animateStat(name, value)
local data = statCards[name]
if not data then
return
end
data.Value.Text = tostring(value)
data.Value.TextTransparency = 1
TweenService:Create(
data.Value,
TweenInfo.new(
0.2,
Enum.EasingStyle.Quint,
Enum.EasingDirection.Out
),
{
TextTransparency = 0
}
):Play()
end
local function calculateDPS(unit)
local directDPS = findStat(unit, "DPS")
if directDPS ~= "N/A" then
return directDPS
end
local damage = findStat(unit, "Damage")
local cooldown = findStat(unit, "Cooldown")
if type(damage) == "number"
and type(cooldown) == "number"
and cooldown > 0 then
return math.round((damage / cooldown) * 100) / 100
end
return "N/A"
end
local function showUnitStats(unit)
selectedUnit = unit
selectedUnitName = unit.Name
selectedTitle.Text = unit.Name
subtitle.Text = "EXISTING UNIT / TOWER"
animateStat("Damage", findStat(unit, "Damage"))
animateStat("Range", findStat(unit, "Range"))
animateStat("Cooldown", findStat(unit, "Cooldown"))
animateStat("Price", findStat(unit, "Price"))
animateStat("DPS", calculateDPS(unit))
statsScroll.CanvasPosition = Vector2.new(0, 0)
for button, buttonUnit in pairs(towerButtons) do
if buttonUnit == unit then
button.BackgroundColor3 = Color3.fromRGB(62, 100, 175)
else
button.BackgroundColor3 = Color3.fromRGB(40, 42, 53)
end
end
end
local function createTowerButton(unit)
local button = Instance.new("TextButton")
button.Name = unit.Name
button.Size = UDim2.new(1, -4, 0, 42)
button.BackgroundColor3 = Color3.fromRGB(40, 42, 53)
button.BorderSizePixel = 0
button.Text = unit.Name
button.TextColor3 = Color3.fromRGB(240, 240, 245)
button.TextSize = 11
button.Font = Enum.Font.GothamMedium
button.TextTruncate = Enum.TextTruncate.AtEnd
button.AutoButtonColor = false
button.Parent = towerList
local corner = Instance.new("UICorner")
corner.CornerRadius = UDim.new(0, 7)
corner.Parent = button
towerButtons[button] = unit
button.MouseEnter:Connect(function()
if selectedUnit ~= unit then
TweenService:Create(
button,
TweenInfo.new(0.1),
{
BackgroundColor3 = Color3.fromRGB(50, 53, 66)
}
):Play()
end
end)
button.MouseLeave:Connect(function()
if selectedUnit ~= unit then
TweenService:Create(
button,
TweenInfo.new(0.1),
{
BackgroundColor3 = Color3.fromRGB(40, 42, 53)
}
):Play()
end
end)
button.Activated:Connect(function()
showUnitStats(unit)
end)
end
local function refreshTowers()
for button in pairs(towerButtons) do
if button and button.Parent then
button:Destroy()
end
end
table.clear(towerButtons)
local objects = getAllUnitsAndTowers()
if #objects == 0 then
listTitle.Text = "NO TOWERS FOUND"
return
end
for _, object in ipairs(objects) do
createTowerButton(object)
end
listTitle.Text = "TOWERS • " .. tostring(#objects)
task.defer(function()
towerList.CanvasPosition = Vector2.new(0, 0)
end)
end
refreshTowers()
--==================================================
-- AUTO REFRESH
--==================================================
local function isInsideUnitTowerFolder(object)
local current = object
while current and current ~= ReplicatedStorage do
if isUnitTowerFolder(current) then
return true
end
current = current.Parent
end
return false
end
ReplicatedStorage.DescendantAdded:Connect(function(object)
if isUnitTowerFolder(object)
or isInsideUnitTowerFolder(object) then
task.defer(refreshTowers)
end
end)
ReplicatedStorage.DescendantRemoving:Connect(function(object)
if isUnitTowerFolder(object)
or isInsideUnitTowerFolder(object) then
task.defer(refreshTowers)
end
end)
--==================================================
-- SPAWN AREA
--==================================================
local spawnArea = Instance.new("Frame")
spawnArea.Name = "SpawnArea"
spawnArea.AnchorPoint = Vector2.new(0, 1)
spawnArea.Position = UDim2.new(0, 7, 1, -7)
spawnArea.Size = UDim2.new(1, -14, 0, 50)
spawnArea.BackgroundColor3 = Color3.fromRGB(25, 27, 36)
spawnArea.BorderSizePixel = 0
spawnArea.Parent = right
local spawnAreaCorner = Instance.new("UICorner")
spawnAreaCorner.CornerRadius = UDim.new(0, 9)
spawnAreaCorner.Parent = spawnArea
local spawnButton = Instance.new("TextButton")
spawnButton.Name = "SpawnButton"
spawnButton.Position = UDim2.fromOffset(6, 6)
spawnButton.Size = UDim2.new(1, -12, 1, -12)
spawnButton.BackgroundColor3 = Color3.fromRGB(55, 165, 95)
spawnButton.BorderSizePixel = 0
spawnButton.Text = "SPAWN SELECTED"
spawnButton.TextColor3 = Color3.new(1, 1, 1)
spawnButton.TextSize = 11
spawnButton.Font = Enum.Font.GothamBold
spawnButton.AutoButtonColor = false
spawnButton.Parent = spawnArea
local spawnCorner = Instance.new("UICorner")
spawnCorner.CornerRadius = UDim.new(0, 8)
spawnCorner.Parent = spawnButton
--==================================================
-- SPAWN NAMES
--==================================================
local spawnNames = {
"SpawnTower",
"spawnTower",
"SPAWNTOWER",
"PlaceTower",
"placeTower",
"PLACETOWER",
"SpawnUnit",
"spawnUnit",
"SPAWNUNIT",
"PlaceUnit",
"placeUnit",
"PLACEUNIT",
"DeployTower",
"deployTower",
"DEPLOYTOWER",
"DeployUnit",
"deployUnit",
"DEPLOYUNIT",
"CreateTower",
"createTower",
"CREATETOWER",
"CreateUnit",
"createUnit",
"CREATEUNIT",
"BuildTower",
"buildTower",
"BUILDTOWER",
"BuildUnit",
"buildUnit",
"BUILDUNIT",
"TowerPlace",
"towerPlace",
"TOWERPLACE",
"UnitPlace",
"unitPlace",
"UNITPLACE",
"TowerSpawn",
"towerSpawn",
"TOWERSPAWN",
"UnitSpawn",
"unitSpawn",
"UNITSPAWN",
"TroopSpawn",
"troopSpawn",
"TROOPSPAWN",
"SpawnTroop",
"spawnTroop",
"SPAWNTROOP",
"PlaceTroop",
"placeTroop",
"PLACETROOP",
"DeployTroop",
"deployTroop",
"DEPLOYTROOP",
"CreateTroop",
"createTroop",
"CREATETROOP",
"BuildTroop",
"buildTroop",
"BUILDTROOP",
"RequestSpawn",
"requestSpawn",
"REQUESTSPAWN",
"SpawnRequest",
"spawnRequest",
"SPAWNREQUEST",
"RequestTower",
"requestTower",
"REQUESTTOWER",
"RequestUnit",
"requestUnit",
"REQUESTUNIT",
"RequestTroop",
"requestTroop",
"REQUESTTROOP",
"SummonTower",
"summonTower",
"SUMMONTOWER",
"SummonUnit",
"summonUnit",
"SUMMONUNIT",
"SummonTroop",
"summonTroop",
"SUMMONTROOP",
"SpawnRequestTower",
"spawnRequestTower",
"SPAWNREQUESTTOWER",
"SpawnRequestUnit",
"spawnRequestUnit",
"SPAWNREQUESTUNIT",
"RequestSpawnTower",
"requestSpawnTower",
"REQUESTSPAWNTOWER",
"RequestSpawnUnit",
"requestSpawnUnit",
"REQUESTSPAWNUNIT",
"Spawn_Tower",
"spawn_tower",
"Spawn_Unit",
"spawn_unit",
"SpawnRequest_Tower",
"spawnRequest_Tower",
"SpawnRequest_Unit",
"spawnRequest_Unit",
}
local function findSpawnRemote()
local containers = {}
local functionsFolder = ReplicatedStorage:FindFirstChild("Functions")
if functionsFolder then
table.insert(containers, functionsFolder)
end
local remoteFunctions = ReplicatedStorage:FindFirstChild("RemoteFunctions")
if remoteFunctions then
table.insert(containers, remoteFunctions)
end
local remoteEvents = ReplicatedStorage:FindFirstChild("RemoteEvents")
if remoteEvents then
table.insert(containers, remoteEvents)
end
table.insert(containers, ReplicatedStorage)
for _, container in ipairs(containers) do
for _, wantedName in ipairs(spawnNames) do
local remote = container:FindFirstChild(wantedName, true)
if remote
and (
remote:IsA("RemoteFunction")
or remote:IsA("RemoteEvent")
) then
return remote
end
end
end
return nil
end
--==================================================
-- SPAWN SELECTED
--==================================================
spawnButton.Activated:Connect(function()
if not selectedUnitName then
selectedTitle.Text = "SELECT A UNIT OR TOWER"
return
end
local character = player.Character
if not character then
character = player.CharacterAdded:Wait()
end
local root = character:FindFirstChild("HumanoidRootPart")
if not root then
selectedTitle.Text = "CHARACTER NOT READY"
return
end
local spawnRemote = findSpawnRemote()
if not spawnRemote then
warn("No tower/unit spawn RemoteFunction or RemoteEvent was found.")
selectedTitle.Text = "SPAWN REMOTE NOT FOUND"
return
end
local success, result = pcall(function()
if spawnRemote:IsA("RemoteFunction") then
return spawnRemote:InvokeServer(
selectedUnitName,
root.CFrame
)
elseif spawnRemote:IsA("RemoteEvent") then
spawnRemote:FireServer(
selectedUnitName,
root.CFrame
)
return true
end
end)
if not success then
warn("Spawn request failed:", result)
selectedTitle.Text = "SPAWN REQUEST FAILED"
else
print(
"Spawn request sent:",
spawnRemote:GetFullName(),
selectedUnitName
)
end
end)
--==================================================
-- SPAWN BUTTON ANIMATION
--==================================================
spawnButton.MouseEnter:Connect(function()
TweenService:Create(
spawnButton,
TweenInfo.new(0.1),
{
BackgroundColor3 = Color3.fromRGB(65, 185, 105)
}
):Play()
end)
spawnButton.MouseLeave:Connect(function()
TweenService:Create(
spawnButton,
TweenInfo.new(0.1),
{
BackgroundColor3 = Color3.fromRGB(55, 165, 95)
}
):Play()
end)
--==================================================
-- HIDE / SHOW
--==================================================
local showButton = Instance.new("TextButton")
showButton.Name = "ShowHub"
showButton.AnchorPoint = Vector2.new(0, 0.5)
showButton.Position = UDim2.new(0, 10, 0.5, 0)
showButton.Size = UDim2.fromOffset(52, 52)
showButton.BackgroundColor3 = Color3.fromRGB(35, 38, 49)
showButton.BorderSizePixel = 0
showButton.Text = "☰"
showButton.TextColor3 = Color3.new(1, 1, 1)
showButton.TextSize = 22
showButton.Font = Enum.Font.GothamBold
showButton.Visible = false
showButton.Parent = gui
local showCorner = Instance.new("UICorner")
showCorner.CornerRadius = UDim.new(1, 0)
showCorner.Parent = showButton
local showStroke = Instance.new("UIStroke")
showStroke.Color = Color3.fromRGB(65, 68, 82)
showStroke.Parent = showButton
hideButton.Activated:Connect(function()
main.Visible = false
showButton.Visible = true
end)
showButton.Activated:Connect(function()
main.Visible = true
showButton.Visible = false
end)
--==================================================
-- PC + MOBILE DRAGGING
--==================================================
local dragging = false
local dragStart = nil
local startPosition = nil
local dragInput = nil
top.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1
or input.UserInputType == Enum.UserInputType.Touch then
dragging = true
dragStart = input.Position
startPosition = main.Position
dragInput = input
end
end)
top.InputEnded:Connect(function(input)
if input == dragInput
or input.UserInputType == Enum.UserInputType.MouseButton1
or input.UserInputType == Enum.UserInputType.Touch then
dragging = false
dragInput = nil
end
end)
UserInputService.InputChanged:Connect(function(input)
if not dragging then
return
end
if input.UserInputType ~= Enum.UserInputType.MouseMovement
and input.UserInputType ~= Enum.UserInputType.Touch then
return
end
if not dragStart or not startPosition then
return
end
local delta = input.Position - dragStart
main.Position = UDim2.new(
startPosition.X.Scale,
startPosition.X.Offset + delta.X,
startPosition.Y.Scale,
startPosition.Y.Offset + delta.Y
)
end)
--==================================================
-- FINALIZE
--==================================================
main.Visible = true
gui.Enabled = true
task.defer(function()
updateScale()
end)
print("TowerHub loaded.")
![[KEYLESS] Moondiety Script | 17+ supported Games](https://scriptblox.com/images/sb/0-1753093706828.png)


My script got accidentally deleted or something
@Pikangi i thought you delete your script(your script is W
Yo Pikangi The Gui Does not show up anymore could you Pls Fix It
@jp05gloria bc the script is not Approved probably
Gui won't show please fix it daddy pikangi
Ohhh ok
gng like 3 hours ago the gui won't appear I'm absolutely sure this isn't an executor problem
Omg bro gui won't show up again