Draggable PlayerList and ExperienceChat
Key RequiredUniversal

Draggable PlayerList and ExperienceChat

Universal ScriptIrfannnnnIrfannnnn 375 views 14 executesUpdated Jan 6, 2026
4.0/ 5(5 votes)
4180% Positive
Lua Script•140 lines (4128 chars)
local UserInputService = game:GetService("UserInputService")
local CoreGui = game:GetService("CoreGui")
local HttpService = game:GetService("HttpService")
local RunService = game:GetService("RunService")

local CONFIG_FILE = "dragsaved.txt"
local DRAG_SPEED = 0.05

local savedPositions = {}
local connections = {}

if isfile(CONFIG_FILE) then
    local success, result = pcall(function()
        return HttpService:JSONDecode(readfile(CONFIG_FILE))
    end)
    if success and type(result) == "table" then
        savedPositions = result
    end
end

local function saveConfig()
    writefile(CONFIG_FILE, HttpService:JSONEncode(savedPositions))
end

local function makeDraggable(frame, uniqueId)
    if not frame then return end
    
    if connections[uniqueId] then
        for _, conn in pairs(connections[uniqueId]) do
            conn:Disconnect()
        end
        connections[uniqueId] = {}
    else
        connections[uniqueId] = {}
    end

    if savedPositions[uniqueId] then
        local posData = savedPositions[uniqueId]
        frame.Position = UDim2.new(posData.Xs, posData.Xo, posData.Ys, posData.Yo)
    end

    local dragging = false
    local dragInput
    local dragStart
    local startPos

    local inputBegan = frame.InputBegan:Connect(function(input)
        if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
            dragging = true
            dragStart = input.Position
            startPos = frame.Position
            
            input.Changed:Connect(function()
                if input.UserInputState == Enum.UserInputState.End then
                    dragging = false
                    
                    savedPositions[uniqueId] = {
                        Xs = frame.Position.X.Scale,
                        Xo = frame.Position.X.Offset,
                        Ys = frame.Position.Y.Scale,
                        Yo = frame.Position.Y.Offset
                    }
                    saveConfig()
                end
            end)
        end
    end)

    local inputChanged = frame.InputChanged:Connect(function(input)
        if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
            dragInput = input
        end
    end)

    local globalInputChanged = UserInputService.InputChanged:Connect(function(input)
        if input == dragInput and dragging then
            local delta = input.Position - dragStart
            
            local targetPos = UDim2.new(
                startPos.X.Scale, 
                startPos.X.Offset + delta.X, 
                startPos.Y.Scale, 
                startPos.Y.Offset + delta.Y
            )
            
            frame.Position = targetPos
        end
    end)

    table.insert(connections[uniqueId], inputBegan)
    table.insert(connections[uniqueId], inputChanged)
    table.insert(connections[uniqueId], globalInputChanged)
end

local function hookPlayerList()
    local path = CoreGui:FindFirstChild("PlayerList")
    if not path then return end
    
    local function setup(child)
        if child.Name == "Children" and child:IsA("Frame") then
            task.wait() 
            makeDraggable(child, "PlayerList_Children")
        end
    end

    if path:FindFirstChild("Children") then
        setup(path.Children)
    end

    path.ChildAdded:Connect(setup)
end

local function hookExperienceChat()
    local path = CoreGui:FindFirstChild("ExperienceChat")
    if not path then return end

    local function setup(child)
        if child.Name == "appLayout" and child:IsA("Frame") then
            task.wait()
            makeDraggable(child, "ExperienceChat_AppLayout")
        end
    end

    if path:FindFirstChild("appLayout") then
        setup(path.appLayout)
    end

    path.ChildAdded:Connect(setup)
end

task.spawn(hookPlayerList)
task.spawn(hookExperienceChat)

CoreGui.ChildAdded:Connect(function(child)
    if child.Name == "PlayerList" then
        hookPlayerList()
    elseif child.Name == "ExperienceChat" then
        hookExperienceChat()
    end
end)

Features & Information

TESTED ON XENO Created by me Features: - Auto Save Current Position (it saved into `dragsaved.txt`) - Auto Load When Executed - Draggable ExperienceChat - Draggable PlayerList OPEN SOURCE
#draggable#playerlist#experiencechat

Community Comments (3)

IrfannnnnIrfannnnnJan 6, 2026

@SheScripts sure

coisye844coisye844Jan 6, 2026

Bro can I danlowed to the ios

Replying to @coisye844
IrfannnnnIrfannnnnJan 6, 2026

@coisye844 yes, if you have executor for roblox ios

More Scripts for Universal Scripts