Robloxでプレイヤーごとにデータを保存する

以下の記事でプレイヤーデータをセーブする方法について解説したが、ここではセーブ用のキーにダミーのユーザidを利用していたため実用はできなかった。

今回は実際のゲームでも利用できるようにユーザーidの取得から実際にデータを保存するところまでやっていく

プレイヤーがゲームに参加したときにデータをロードする

ServerScriptService配下にScriptを作成、名前をDataStoreLoaderとする

プレイヤーがゲームに参加したときにデータをロード、それをリーダーボードに登録する

-- Playerを利用するためのサービクラスを取得
local Players = game:GetService("Players")
-- DataStoreを利用するためのサービスクラスを取得
local DataStoreService = game:GetService("DataStoreService")
-- Dummyという名前のDataStoreを取得/生成する
local dummyStore = DataStoreService:GetDataStore("Dummy")

local function loadPlayerData(player)
	-- userIdからData用のキーを生成する
	local datakey = player.userId.."-dummData"
	
	-- 成功するまでデータのロードを試みる
	local value
	repeat
		local success, errorMessage = pcall(function()
			value = dummyStore:GetAsync(datakey)
		end)
		wait(1)
	until(success)
	
	-- リーダーボード作成、登録
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player
	local stage = Instance.new("IntValue")
	stage.Name = "Dummy"
	stage.Value = value
	stage.Parent = leaderstats	
end

-- プレイヤーがゲームに参加したときのイベントを登録する
Players.PlayerAdded:Connect(loadPlayerData)

結果

プレイヤーがゲームから出るときにデータをセーブする

ServerScriptService配下にScriptを作成、名前をDataStoreSaverとする

プレイヤーがゲームから出ようとしているときにリーダーボードのデータを読み、保存する

-- Playerを利用するためのサービクラスを取得
local Players = game:GetService("Players")
-- DataStoreを利用するためのサービスクラスを取得
local DataStoreService = game:GetService("DataStoreService")
-- Dummyという名前のDataStoreを取得/生成する
local dummyStore = DataStoreService:GetDataStore("Dummy")


local function savePlayerData(player)
	-- userIdからData用のキーを生成する
	local datakey = player.userId.."-dummData"
	
	-- データを保存する
	local data = tonumber(player.leaderstats.Dummy.Value)
	repeat
		local success, errormessage = pcall(function()				
			dummyStore:SetAsync(datakey, data)
		end)
	until (success)

end

-- プレイヤーがゲームから出ようとしたときのイベントを登録する
Players.PlayerRemoving:Connect(savePlayerData)

このままではゲーム中にデータが更新されないため、常に0をセーブし、0を書き込むことになる

ちゃんとデータのセーブ/ロードができていることを確認するためにゲーム中にデータを更新する

ServerScriptService配下にScriptを作成、名前をDataUpdaterとする

一定間隔でデータを更新する処理を記述する

-- Playerを利用するためのサービクラスを取得
local Players = game:GetService("Players")

-- 5秒に一度データを1増やす
while true do
	wait(5)
	for _, player in pairs(Players:GetPlayers()) do
		player.leaderstats.Dummy.Value += 1
	end
end

結果

右上に表示されているリーダーボードの値がゲームを終了しても保持されている

※注意 RobloxStudioでテストプレイしている状態でゲームを終了した場合、PlayerRemovingで実行した非同期処理が正常に終了しない。そのため上記の動作テストではゲームを公開してそこから実行している。