← 全部教程
数据
如何制作 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)
end2. 读取前列玩家
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) 当键,这样每个玩家正好对应一条记录。
