プレイヤーがコインを集めたことを検出できるようになったので、プレイヤーが集めたコインの数をカウントし、その数をリーダーボードに表示する必要があります。
コイン収集を記録するモジュールスクリプトを作成する
各プレイヤーのコイン収集データの保存と管理を行うために、コイン収集データにアクセスするためのデータ構造と関数を含む ModuleScript オブジェクトを作成する必要があります。モジュールスクリプトは、他のスクリプトが要求できる再利用可能なコードです。この場合、CoinServiceはプレイヤーがコインに触れたときにコイン収集データを更新できるように、このモジュールスクリプトを要求します。
ServerStorageに、次のコードを持つPlayerDataという名前のModuleScriptを作成します。
```lua
local PlayerData = {}
PlayerData.COIN_KEY_NAME = "Coins"
local playerData = {
--[[
[userId: string] = {
["Coins"] = coinAmount: number
}
]]
}
local function defaultPlayerData()
return {
[PlayerData.COIN_KEY_NAME] = 0
}
end
local function getData(player)
local data = playerData[tostring(player.UserId)] or defaultPlayerData()
playerData[tostring(player.UserId)] = data
return data
end
function PlayerData.getValue(player, key)
return getData(player)[key]
end
function PlayerData.updateValue(player, key, updateFunction)
local data = getData(player)
local oldValue = data[key]
local newValue = updateFunction(oldValue)
data[key] = newValue
return newValue
end
return PlayerData
```モジュールスクリプトは、プレイヤーのコイン収集データを表すゼロまたは多数の playerData テーブルを含む PlayerData テーブルを定義します。このモジュールスクリプトを要求するすべてのスクリプトは、同じ PlayerData テーブルのコピーを受け取るため、複数のスクリプトがコイン収集データを変更および共有できます。
データ構造の宣言
モジュールスクリプトは、空のテーブル PlayerData の宣言から始まり、スクリプトの最後で返されます。また、テーブル内の値を取得および設定するためのアクセサーメソッドも含まれています。
playerData テーブルには、テーブルの構造を説明するコメントが含まれており、コードの理解が容易になります。この場合、playerData テーブルには userId と、そのプレイヤーの収集したコインの量を表す Coins という対応するフィールドが含まれています。
local PlayerData = {}
PlayerData.COIN_KEY_NAME = "Coins"
local playerData = {
--[[
[userId: string] = {
["Coins"] = coinAmount: number
}
]]
}
...
return PlayerDataローカルデータアクセサの定義
getData() は特定の playerData テーブルのデータを取得するローカル関数です。プレイヤーがコインを収集していない場合、すべてのプレイヤーに関連付けられたデータがあることを保証するために、defaultPlayerData() 関数からテーブルを返します。一般的な慣習として、ロジックをローカルスコープの関数にオフロードするシンプルで公開向けの関数を作成します。
local function defaultPlayerData()
return {
[PlayerData.COIN_KEY_NAME] = 0
}
end
local function getData(player)
local data = playerData[tostring(player.UserId)] or defaultPlayerData()
playerData[tostring(player.UserId)] = data
return data
end公開データアクセサの定義
getValue() と updateValue() は、他のスクリプトがこのモジュールスクリプトを要求して呼び出すことができる公開向けの関数です。この場合、CoinService は、プレイヤーがコインに触れるたびにこれらの関数を使用してプレイヤーのコイン収集データを更新します。
function PlayerData.getValue(player, key)
return getData(player)[key]
end
function PlayerData.updateValue(player, key, updateFunction)
local data = getData(player)
local oldValue = data[key]
local newValue = updateFunction(oldValue)
data[key] = newValue
return newValue
endリーダーボードを実装する
コイン収集データを視覚的に表現するために、画面上にリーダーボードを表示できます。Robloxには、デフォルトのUIを使用して自動的にリーダーボードを生成する組み込みシステムが含まれています。
ServerStorageに、次のコードを持つLeaderboardという名前のModuleScriptを作成します。
```lua
local Leaderboard = {}
-- 新しいリーダーボードを作成
local function setupLeaderboard(player)
local leaderstats = Instance.new("Folder")
-- 'leaderstats' は、Robloxがリーダーボードを作成するために認識する予約名です
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
return leaderstats
end
-- 新しいリーダーボードの統計値を作成
local function setupStat(leaderstats, statName)
local stat = Instance.new("IntValue")
stat.Name = statName
stat.Value = 0
stat.Parent = leaderstats
return stat
end
-- プレイヤーの統計値を更新
function Leaderboard.setStat(player, statName, value)
local leaderstats = player:FindFirstChild("leaderstats")
if not leaderstats then
leaderstats = setupLeaderboard(player)
end
local stat = leaderstats:FindFirstChild(statName)
if not stat then
stat = setupStat(leaderstats, statName)
end
stat.Value = value
end
return Leaderboard
```次のセクションでは、リーダーボードの動作について詳しく説明します。
リーダーボードを作成する
setupLeaderboard() 関数は、leaderstats という名前の新しいフォルダーインスタンスを作成し、それを指定されたプレイヤーの子として設定します。Robloxは、leaderstats という名前のフォルダーを統計のコンテナとして自動的に認識し、統計を表示するためのUI要素を作成します。leaderstats 内の値は、「値」オブジェクト(StringValue、IntValue、または NumberValue など)として保存される必要があります。
-- 新しいリーダーボードを作成
local function setupLeaderboard(player)
local leaderstats = Instance.new("Folder")
-- 'leaderstats' は、Robloxがリーダーボードを作成するために認識する予約名です
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
return leaderstats
end
-- 新しいリーダーボードの統計値を作成
local function setupStat(leaderstats, statName)
local stat = Instance.new("IntValue")
stat.Name = statName
stat.Value = 0
stat.Parent = leaderstats
return stat
endプレイヤーの統計を更新する
setStat() は、Leaderboard モジュール内の唯一の公開関数です。指定されたプレイヤーまたはリーダーボード自体のために統計値を作成します。
FindFirstChild() は、オブジェクトの名前を取り、そのオブジェクトが存在する場合はオブジェクトを返し、存在しない場合は nil を返します。オブジェクトを使用する前に存在を確認するための一般的で安全な方法です。
-- プレイヤーの統計値を更新
function Leaderboard.setStat(player, statName, value)
local leaderstats = player:FindFirstChild("leaderstats")
if not leaderstats then
leaderstats = setupLeaderboard(player)
end
local stat = leaderstats:FindFirstChild(statName)
if not stat then
stat = setupStat(leaderstats, statName)
end
stat.Value = value
endモジュールスクリプトを統合する
両方のモジュールが整ったので、CoinService スクリプト内でそれらを要求してプレイヤーのコインデータを管理および表示します。
ServerScriptService内の既存のCoinServiceスクリプトのコードを次のように置き換えます。
```lua
-- サービスと変数の初期化
local Workspace = game:GetService("Workspace")
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
-- モジュール
local Leaderboard = require(ServerStorage.Leaderboard)
local PlayerData = require(ServerStorage.PlayerData)
local coinsFolder = Workspace.World.Coins
local coins = coinsFolder:GetChildren()
local COIN_KEY_NAME = PlayerData.COIN_KEY_NAME
local COOLDOWN = 10
local COIN_AMOUNT_TO_ADD = 1
local function updatePlayerCoins(player, updateFunction)
-- コインテーブルを更新
local newCoinAmount = PlayerData.updateValue(player, COIN_KEY_NAME, updateFunction)
-- コインリーダーボードを更新
Leaderboard.setStat(player, COIN_KEY_NAME, newCoinAmount)
end
-- イベントハンドラーの定義
local function onCoinTouched(otherPart, coin)
if coin:GetAttribute("Enabled") then
local character = otherPart.Parent
local player = Players:GetPlayerFromCharacter(character)
if player then
-- プレイヤーがコインに触れた
coin.Transparency = 1
coin:SetAttribute("Enabled", false)
updatePlayerCoins(player, function(oldCoinAmount)
oldCoinAmount = oldCoinAmount or 0
return oldCoinAmount + COIN_AMOUNT_TO_ADD
end)
task.wait(COOLDOWN)
coin.Transparency = 0
coin:SetAttribute("Enabled", true)
end
end
end
-- イベントリスナーの設定
for _, coin in coins do
coin:SetAttribute("Enabled", true)
coin.Touched:Connect(function(otherPart)
onCoinTouched(otherPart, coin)
end)
end
```元の CoinService スクリプトへの変更には、以下が含まれます。
- プレイヤーがコインを収集したときに追加するコインの数を示す COIN_AMOUNT_TO_ADD と、PlayerData で定義されたキー名を示す COIN_KEY_NAME を宣言します。
- プレイヤーのコイン数と関連するリーダーボードの統計を更新するためのヘルパー関数 updatePlayerCoins() を作成します。
- onCoinTouched() 内のプレースホルダー print() ステートメントを updatePlayerCoins() への呼び出しに置き換えます。
プレイテスト
ドロップダウンから Test を選択し、Play をクリックします。コインに歩き入って、リーダーボードが隅に表示され、コインを集めるにつれてコイン数が増加することを確認します。