Character Picker GUI
Key Required

Character Picker GUI

Legends of EsculoneMediorceExploiterMediorceExploiter 558 views 14 executesUpdated Jan 12, 2026
Unrated
00
Lua Script•203 lines (5381 chars)
-- StarterPlayerScripts/CharacterPickDropdown.client.lua
-- Dropdown GUI to fire character-pick remotes once.
-- Press M to fully unload.

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserInputService = game:GetService("UserInputService")

local player = Players.LocalPlayer
local playerGui = player:WaitForChild("PlayerGui")

-- =========================
-- CONFIG
-- =========================
local GUI_NAME = "CharacterPickDropdown_GUI"
local UNLOAD_KEY = Enum.KeyCode.M

-- Remote names (exact)
local OPTIONS = {
	{ label = "Wizard",      remoteName = "ChacterPickWizard" },
	{ label = "Necromancer", remoteName = "ChacterPickNecromancer" },
	{ label = "Engineer",    remoteName = "ChacterPickEngineer" },
	{ label = "Beserker",    remoteName = "ChacterPickBeserker" },
	{ label = "Archer",      remoteName = "ChacterPickArcher" },
}
-- =========================

-- Remove old GUI copies
do
	local old = playerGui:FindFirstChild(GUI_NAME)
	if old then old:Destroy() end
end

-- =========================
-- UNLOAD SYSTEM
-- =========================
local connections = {}
local unloaded = false

local function connect(signal, fn)
	local c = signal:Connect(fn)
	table.insert(connections, c)
	return c
end

local function unloadAll()
	if unloaded then return end
	unloaded = true

	for _, c in ipairs(connections) do
		pcall(function() c:Disconnect() end)
	end
	table.clear(connections)

	local g = playerGui:FindFirstChild(GUI_NAME)
	if g then g:Destroy() end

	script:Destroy()
end
-- =========================

-- =========================
-- GUI
-- =========================
local gui = Instance.new("ScreenGui")
gui.Name = GUI_NAME
gui.ResetOnSpawn = false
gui.Parent = playerGui

local frame = Instance.new("Frame")
frame.Size = UDim2.new(0, 270, 0, 160)
frame.Position = UDim2.new(0, 20, 0, 120)
frame.BackgroundTransparency = 0.12
frame.Parent = gui

local title = Instance.new("TextLabel")
title.Size = UDim2.new(1, -10, 0, 24)
title.Position = UDim2.new(0, 5, 0, 5)
title.BackgroundTransparency = 1
title.TextScaled = true
title.Text = "Character Pick"
title.Parent = frame

local dropdownBtn = Instance.new("TextButton")
dropdownBtn.Size = UDim2.new(1, -20, 0, 32)
dropdownBtn.Position = UDim2.new(0, 10, 0, 40)
dropdownBtn.TextScaled = true
dropdownBtn.Text = "Select Class ▼"
dropdownBtn.Parent = frame

local listFrame = Instance.new("Frame")
listFrame.Size = UDim2.new(1, -20, 0, 0) -- collapsed by default
listFrame.Position = UDim2.new(0, 10, 0, 72)
listFrame.BackgroundTransparency = 0.1
listFrame.ClipsDescendants = true
listFrame.Parent = frame

local listLayout = Instance.new("UIListLayout")
listLayout.SortOrder = Enum.SortOrder.LayoutOrder
listLayout.Padding = UDim.new(0, 4)
listLayout.Parent = listFrame

local fireBtn = Instance.new("TextButton")
fireBtn.Size = UDim2.new(1, -20, 0, 32)
fireBtn.Position = UDim2.new(0, 10, 0, 112)
fireBtn.TextScaled = true
fireBtn.Text = "Fire Selected"
fireBtn.Parent = frame

-- Draggable
do
	local dragging = false
	local dragStart, startPos

	connect(frame.InputBegan, function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			dragging = true
			dragStart = input.Position
			startPos = frame.Position
		end
	end)

	connect(UserInputService.InputChanged, function(input)
		if not dragging then return end
		if input.UserInputType ~= Enum.UserInputType.MouseMovement then return end
		local delta = input.Position - dragStart
		frame.Position = UDim2.new(
			startPos.X.Scale, startPos.X.Offset + delta.X,
			startPos.Y.Scale, startPos.Y.Offset + delta.Y
		)
	end)

	connect(UserInputService.InputEnded, function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			dragging = false
		end
	end)
end
-- =========================

-- =========================
-- DROPDOWN LOGIC
-- =========================
local dropdownOpen = false
local selected = nil -- {label, remoteName}

local function setDropdownOpen(open)
	dropdownOpen = open
	if dropdownOpen then
		-- open to fit 5 buttons
		listFrame.Size = UDim2.new(1, -20, 0, 5 * 28 + 4 * 4 + 8)
		dropdownBtn.Text = (selected and (selected.label .. " ▼") or "Select Class ▼")
	else
		listFrame.Size = UDim2.new(1, -20, 0, 0)
		dropdownBtn.Text = (selected and (selected.label .. " ▼") or "Select Class ▼")
	end
end

-- Build dropdown items
for _, opt in ipairs(OPTIONS) do
	local b = Instance.new("TextButton")
	b.Size = UDim2.new(1, -10, 0, 28)
	b.Position = UDim2.new(0, 5, 0, 0)
	b.TextScaled = true
	b.Text = opt.label
	b.Parent = listFrame

	connect(b.MouseButton1Click, function()
		selected = opt
		setDropdownOpen(false)
		dropdownBtn.Text = opt.label .. " ▼"
	end)
end

connect(dropdownBtn.MouseButton1Click, function()
	setDropdownOpen(not dropdownOpen)
end)

connect(fireBtn.MouseButton1Click, function()
	if not selected then
		warn("Select a class first.")
		return
	end

	local remote = ReplicatedStorage:FindFirstChild(selected.remoteName)
	if not remote then
		warn("Remote not found in ReplicatedStorage:", selected.remoteName)
		return
	end

	remote:FireServer()
end)

-- Unload hotkey
connect(UserInputService.InputBegan, function(input, gameProcessed)
	if gameProcessed then return end
	if input.KeyCode == UNLOAD_KEY then
		unloadAll()
	end
end)

setDropdownOpen(false)
print("CharacterPickDropdown loaded. Press M to unload.")

Features & Information

Lets you change your class to any other class in the game while keeping the same stats.
#op#legends of esculone

Community Comments (0)

No comments yet for this script.

More Scripts for Legends of Esculone