Roblox GUI Maker
← 全部教程

数据

如何制作 Roblox 全局排行榜 GUI

全局排行榜按某个统计(比如总金币)给每个玩家排名,而且排名跨服保留。难的不是 GUI —— 而是用 OrderedDataStore 存储可排序数据并把前列玩家读回来。本指南覆盖完整闭环:保存分数、取前 10 名、把它们渲染成行。从排行榜模板开始可以得到行布局。

打开排行榜 模板 →

1. 用 OrderedDataStore 存储可排名数据

OrderedDataStore 保持值可排序。用玩家的 UserId 当键、分数当值,这样每个玩家只出现一次。

local DataStoreService = game:GetService("DataStoreService")
local scores = DataStoreService:GetOrderedDataStore("CoinsLeaderboard")

local function saveScore(player, coins)
	scores:UpdateAsync(tostring(player.UserId), function(old)
		return math.max(old or 0, coins)
	end)
end

2. 读取前列玩家

GetSortedAsync 按顺序返回条目。传 false 表示降序(最高在前)和页大小。GetCurrentPage 给出排好序的 { key, value } 列表。

local function getTop(n)
	local page = scores:GetSortedAsync(false, n)
	local entries = {}
	for _, entry in ipairs(page:GetCurrentPage()) do
		local userId = tonumber(entry.key)
		local player = game:GetService("Players"):GetNameFromUserIdAsync(userId)
		table.insert(entries, { name = player, score = entry.value })
	end
	return entries
end
提示: GetNameFromUserIdAsync 是一次网络调用 —— 把名字缓存起来,免得每次刷新都重新拉同一个玩家。

3. 把列表发给客户端并生成行

用一个 RemoteEvent 把前列列表发出去;每个客户端按条目生成一行。因为面板有 UIListLayout,挂上每一行就自动堆叠。

-- Server
local remote = game.ReplicatedStorage:WaitForChild("LeaderboardUpdate")
task.spawn(function()
	while true do
		remote:FireAllClients(getTop(10))
		task.wait(60) -- refresh once a minute
	end
end)

-- Client: make one row per entry, parented to the panel
local function makeRow(rank, name, score)
	local row = Instance.new("Frame")
	row.Size = UDim2.fromScale(1, 0.14)
	row.Parent = panel
	-- ...rank label, name label, score label...
	return row
end

常见问题

全局排行榜多久刷新一次?

OrderedDataStore 有严格的速率限制。缓存前列列表,用服务端循环每 30–60 秒刷新一次,绝不要在每次分数变化时刷新。

为什么一个玩家出现了两次?

你用了 UserId 以外的东西当键。永远用 tostring(player.UserId) 当键,这样每个玩家正好对应一条记录。

相关教程

不想手写这些样板代码?

本篇教程里的每一项 —— 层级结构、布局助手、按钮连线 —— 都内置在免费的 Roblox GUI 制作器 里。拖拽搭建、直接调 Roblox 真实属性,然后导出可直接粘贴进 Studio 的 Luau 代码。