🔢

【ロブロックス】大きいスコアボードを出す

2025/02/10に公開

概要

この記事でリーダーボードの出し方は分かったけど、もっと大きく表示するためにいろいろ調べました

↓完成したスコアボード

実装の調査

クリエイターストアを調べると「TimePlayedLeaderboard」というちょうど良さそうなのがある

これを設置して中身を見ると328行くらいのスクリプトを持っていて、ユーザーのサムネとか名前をボードに表示している

今回は既存の仕組みの延長で実装したいので使えそうなコードを見て仕組みを勉強しようと思う
ので、実装済みコードは実行されないように最終行の初期化コードをコメントアウト

-- TimePlayedClass.new()

初期化部分

script.Parentで親を参照できるらしい

L16で同階層の「Setting」モジュールスクリプトを呼んでいる

local Config = require(script.Parent.Settings)

L37でスコアボードオブジェクトを取得している

 new._scoreBlock = script.Parent.ScoreBlock

L165でスコアボードはsufgui変数に代入されている

  local sufgui = self._scoreBlock.Leaderboard

L78でデータストアを取得

  local suc, err = pcall(function ()
    self._datastore = game:GetService("DataStoreService"):GetOrderedDataStore(self._dataStoreName)
  end)

DataStore

セッションデータらしい(雑
https://create.roblox.com/docs/cloud-services/data-stores

アクセスするにはゲームをロブロックスのサーバにアップロード(保存)する必要がある

  1. Go to Home > Game Settings > Security.
  2. Enable the Enable Studio Access to API Services toggle.
  3. Click Save.

ボード更新部分

L178でData storesからとってきたresultsをループして値を変更していた
..はLuaの文字列連結の構文なので Nme1, Name2, ... と更新していっている

    sufgui.Names["Name"..k].Text = name
    sufgui.Score["Score"..k].Text = score
    sufgui.Photos["Photo"..k].Image = thumbnail

データ取得部分

L156でData storesからデータを10件取得している

  local suc, results = pcall(function ()
    return self._datastore:GetSortedAsync(false, 10, 1):GetCurrentPage()
  end)

Luaのテーブル型になっている
このアセットのコードではTopTimePlayedという名前でデータを保存している

今回はこの実装はスキップしてPlayersに保存したLeaderstatsの値をボードに反映させようと思う

ボードの実装

最終的にPlayersから取得できたのでそれで実装してみました
本当はPlayer情報はData storesからとってくるのが綺麗なのかもしれない…これは後日試してみようかと思います

最終的なコードと実装

luaのTableの処理になれなかったので微妙なコードになった気がします
もっと効率よくソートしたり、一つのTbleだけで実装できると思うので後日リファクタ予定

local Players = game:GetService("Players")

function getPlayersScoreList(players)
	print("Start getPlayersScoreList")
	local pointList =       {}
	local thumbnaiList =       {}
	for currentPlayer = 1, #players do
		local player = players[currentPlayer]
		print("===user id===")
		print(player.UserId)
		local thumbnail = Players:GetUserThumbnailAsync(player.UserId, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size150x150)
		print(thumbnail)
		local points = player.leaderstats.Points
		print(points.value)
		pointList[player.Name] = points.value
		thumbnaiList[player.Name] = thumbnail
	end
	
	return {pointList, thumbnaiList}
end

function geteSortedKeys(results)
	local keys = {}
	for k in pairs(results) do
		table.insert(keys, k)
	end
	print(keys)

	table.sort(keys, function(a, b)
		return results[a] > results[b]  -- 降順
	end)

	return keys
end

function updateScoreBoard(sortedKeys, pointList, thumbnailList)
	local scorBoard = script.Parent.ScoreBlock
	print(scorBoard)
	for index, name in ipairs(sortedKeys) do
		print("index", index)
		print(scorBoard.Leaderboard.Names)
		scorBoard.Leaderboard.Names["Name"..index].Text = name
		scorBoard.Leaderboard.Score["Score"..index].Text = pointList[name]
		scorBoard.Leaderboard.Photos["Photo"..index].Image = thumbnailList[name]

		if index == 10 then
			break  -- 10回で終了
		end
	end
end

function startBoard()
	print("Start scor board!")
	
	-- 2秒に一回プレイヤー一覧からボードを更新
	while true do
		local playerList = Players:GetPlayers()
		print(playerList)
		if #playerList >= 1 then
			local results = getPlayersScoreList(playerList)
			print("PlayersScoreList")
			print(results)
			local sortedKeys = geteSortedKeys(results[1])
			updateScoreBoard(sortedKeys, results[1], results[2])
		end
		task.wait(2)
	end
end

startBoard()

Discussion