Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- This script relies on a modular framework I wrote. Since I use modules it's harder to get a 200 line+ script, so I wrote up this one in around 40 minutes without any tutorials. My post on my framework is below.
- -- https://devforum.roblox.com/t/code-framework-and-structure/3059321
- -- [ SERVICES ]
- local Players = game:GetService("Players")
- local Teams = game:GetService("Teams")
- local ContextActionService = game:GetService("ContextActionService")
- local StarterGui = game:GetService("StarterGui")
- local TweenService = game:GetService("TweenService")
- local UserInputService = game:GetService("UserInputService")
- -- [ FOLDER ]
- local Assets = script:WaitForChild("Assets")
- -- [ MODULES ]
- local Settings = require(script:WaitForChild("Settings"))
- -- [ VARIABLES ]
- local LocalPlayer : Player = game.Players.LocalPlayer
- local PlayerGui = LocalPlayer:WaitForChild("PlayerGui")
- local LeaderboardHandler = {}
- local TeamConnections = {}
- local LatestTeamIndexList = {}
- local LeaderboardOpen = true
- local PlayerFrame = Assets:WaitForChild("PlayerFrame")
- local TeamFrame = Assets:WaitForChild("Team")
- local LeaderboardUI
- local MainFrame
- local OpenCloseButton
- -- [ FUNCTIONS ]
- local function ClearList()
- for _, frame in pairs(MainFrame:GetChildren()) do
- if frame:IsA("Frame") then
- frame:Destroy()
- end
- end
- end
- local function PlayerToFrame(player : Player, index : number) : Frame
- local playerFrame = PlayerFrame:Clone()
- -- Setup the player's name and image.
- playerFrame.Image.Image = Players:GetUserThumbnailAsync(player.UserId, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size420x420)
- playerFrame.DisplayName.Text = player.DisplayName
- playerFrame.Username.Text = "@"..player.Name
- playerFrame.LayoutOrder = index
- playerFrame.Name = player.UserId
- -- Check if the user is in settings.
- if Settings.CustomIcons[player.UserId] then
- playerFrame.Icon.Image = "http://www.roblox.com/asset/?id="..tostring(Settings.CustomIcons[player.UserId].ID)
- playerFrame.Icon.ImageColor3 = Settings.CustomIcons[player.UserId].ImageColor
- playerFrame.Icon.Visible = true
- end
- -- Return
- return playerFrame
- end
- local function TeamToFrame(team : Team, index : number) : Frame
- local teamFrame = TeamFrame:Clone()
- -- Setup the team text.
- teamFrame.TeamName.Text = team.Name
- teamFrame.TeamName.TextColor = team.TeamColor
- teamFrame.LayoutOrder = index
- -- Return
- return teamFrame
- end
- local function FindPlayerFrameInList(player : Player)
- for index, frame : Frame in pairs(MainFrame:GetChildren()) do
- if frame.Name == tostring(player.UserId) then
- return frame
- end
- end
- return nil
- end
- local function GetPlayerLocationInTeams(player : Player, teamIndexTable : {[string]: number}) : number
- -- Find the team.
- local team = player.Team
- -- Search through the index table to find their index.
- for key, index in pairs(teamIndexTable) do
- if key == team then
- return index
- end
- end
- -- Return nil if they weren't in any of the found tables.
- return -1
- end
- local function UserChangedTeam(player : Player)
- -- Find the users frame in the list.
- local frame = FindPlayerFrameInList(player)
- -- Check if it exists.
- if frame then
- -- Grab the users index position in the teams.
- local indexPosition = GetPlayerLocationInTeams(player, LatestTeamIndexList)
- -- Check if the index position exists and update the frame layout order.
- if indexPosition > -1 then
- frame.LayoutOrder = indexPosition
- end
- end
- end
- local function RefreshUI()
- -- Clear the previous list.
- ClearList()
- -- Get the players.
- local PlayerTable = Players:GetPlayers()
- local TeamTable = Teams:GetTeams()
- local TeamIndexTable = {}
- -- Create frames for the teams.
- for index, team : Team in ipairs(TeamTable) do
- -- Grab the correct index. Multiply by 1000 so that more than 1 user can be in that list.
- local correctIndex = index * 1000
- -- Add the team to the index table so we can sort the UI later.
- TeamIndexTable[team] = correctIndex
- -- Create the team frame.
- local teamFrame = TeamToFrame(team, correctIndex)
- teamFrame.Visible = true
- teamFrame.Parent = MainFrame
- end
- -- Update the team index table.
- LatestTeamIndexList = TeamIndexTable
- -- Create frames for each of the players.
- for index, player : Player in ipairs(PlayerTable) do
- -- Grab the users index in the team table.
- local usersIndex = GetPlayerLocationInTeams(player, TeamIndexTable)
- -- Check if the index exists.
- if usersIndex > -1 then
- -- Create the frame and parent it.
- local playerFrame = PlayerToFrame(player, usersIndex + index)
- playerFrame.Parent = MainFrame
- playerFrame.Visible = true
- end
- end
- end
- local function OpenCloseLeaderboard(actionName, inputState : Enum.UserInputState)
- -- Check if the user is beginning the press.
- if inputState ~= Enum.UserInputState.Begin then return end
- -- Check if the leaderboard is already open.
- LeaderboardOpen = not LeaderboardOpen
- -- We hold the tween's properties here.
- local propertyTable = {}
- -- Check if the user is mobile to update the button.
- if OpenCloseButton.Visible == true then
- OpenCloseButton.Text = if LeaderboardOpen then "CLOSE" else "OPEN"
- end
- -- Check if the leaderboard is open.
- if LeaderboardOpen then
- -- The leaderboard needs to be opened.
- propertyTable.Position = Settings.TweeningStyle.OpenPosition
- else
- -- The leaderboard needs to be closed.
- propertyTable.Position = Settings.TweeningStyle.ClosedPosition
- end
- -- Create the tween and play it.
- local lbInfo = Settings.TweeningStyle.LeaderboardTweenInfo
- local tween = TweenService:Create(MainFrame.Parent, lbInfo, propertyTable)
- tween:Play()
- end
- local function SetupUI()
- -- Place the leaderboard UI on the playergui.
- LeaderboardUI = Assets:WaitForChild("Leaderboard"):Clone()
- LeaderboardUI.Parent = PlayerGui
- -- Set up the variables for the frames.
- MainFrame = LeaderboardUI:WaitForChild("Frame"):WaitForChild("MainFrame")
- OpenCloseButton = LeaderboardUI:WaitForChild("Frame"):WaitForChild("OpenClose")
- -- Check if the user is mobile.
- if UserInputService.TouchEnabled then
- -- Enable the close button and listen for touches.
- OpenCloseButton.Visible = true
- OpenCloseButton.Text = if LeaderboardOpen then "CLOSE" else "OPEN"
- OpenCloseButton.MouseButton1Up:Connect(function()
- OpenCloseLeaderboard(nil, Enum.UserInputState.Begin)
- end)
- else
- -- Disable the close button.
- OpenCloseButton.Visible = false
- end
- -- Loop through all the current players and connect to them.
- for index, player : Player in pairs(Players:GetPlayers()) do
- -- Check if the user is already connected.
- if not TeamConnections[player.UserId] then
- -- Check if the user changed teams.
- TeamConnections[player.UserId] = player:GetPropertyChangedSignal("Team"):Connect(function()
- UserChangedTeam(player)
- end)
- end
- end
- end
- local function PlayerAdded(player : Player)
- -- Connect to the player changing teams.
- TeamConnections[player.UserId] = player:GetPropertyChangedSignal("Team"):Connect(function()
- UserChangedTeam(player)
- end)
- end
- local function PlayerRemoving(player : Player)
- -- Disconnect listening for the team change on leave.
- if TeamConnections[player.UserId] then
- TeamConnections[player.UserId]:Disconnect()
- print("Disconnected from player "..player.DisplayName)
- end
- end
- -- [ INITIALIZATION ]
- function LeaderboardHandler.__init()
- -- Disable the old ui.
- StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.PlayerList, false)
- -- Bind the opening and closing keys.
- ContextActionService:BindAction("Leaderboard", OpenCloseLeaderboard, false, Enum.KeyCode.Tab)
- ContextActionService:SetPosition("Leaderboard", UDim2.new(0.3, 0,-1.2, 0))
- ContextActionService:SetTitle("Leaderboard", "Leaderboard")
- -- Setup the UI and refresh it.
- SetupUI()
- RefreshUI()
- end
- -- [ CONNECTIONS ]
- Players.PlayerAdded:Connect(PlayerAdded)
- Players.PlayerRemoving:Connect(PlayerRemoving)
- -- [ RETURNING ]
- return LeaderboardHandler
Advertisement
Add Comment
Please, Sign In to add comment