今、プレイヤーがコインを収集した時点を検出できるようになったので、プレイヤーが収集したコインの数をカウントし、その量をリーダーボードに表示する必要があります。
コイン収集を記録するためのモジュールスクリプトを作成する
各プレイヤーのコイン収集データの保存と管理を扱うには、すべてのプレイヤーのコイン収集データにアクセスするデータ構造と関数を含む ModuleScript オブジェクトを作成する必要があります。モジュールスクリプトは、他のスクリプトが参照できる再利用可能なコードです。この場合、CoinServiceはこのモジュールスクリプトを必要とし、プレイヤーがコインに触れたときにコイン収集データを更新できるようにします。
Create PlayerDataServerStorage内にPlayerDataという名前のModuleScriptを作成し、以下のコードを入力します。```lualocal PlayerData = {}PlayerData.COIN_KEY_NAME = "Coins"local playerData = {--[[[userId: string] = {["Coins"] = coinAmount: number}]]}local function defaultPlayerData()return {[PlayerData.COIN_KEY_NAME] = 0}endlocal function getData(player)local data = playerData[tostring(player.UserId)] or defaultPlayerData()playerData[tostring(player.UserId)] = datareturn dataendfunction PlayerData.getValue(player, key)return getData(player)[key]endfunction PlayerData.updateValue(player, key, updateFunction)local data = getData(player)local oldValue = data[key]local newValue = updateFunction(oldValue)data[key] = newValuereturn newValueendreturn 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を使用してリーダーボードを自動的に生成するビルトインシステムが含まれています。
Create LeaderboardServerStorage内にLeaderboardという名前のModuleScriptを作成し、以下のコードを入力します。```lualocal Leaderboard = {}-- 新しいリーダーボードを作成するlocal function setupLeaderboard(player)local leaderstats = Instance.new("Folder")-- 'leaderstats' は、リーダーボードを作成するためにRobloxが認識する予約された名前ですleaderstats.Name = "leaderstats"leaderstats.Parent = playerreturn leaderstatsend-- 新しいリーダーボードのスタット値を作成するlocal function setupStat(leaderstats, statName)local stat = Instance.new("IntValue")stat.Name = statNamestat.Value = 0stat.Parent = leaderstatsreturn statend-- プレイヤーのスタット値を更新するfunction Leaderboard.setStat(player, statName, value)local leaderstats = player:FindFirstChild("leaderstats")if not leaderstats thenleaderstats = setupLeaderboard(player)endlocal stat = leaderstats:FindFirstChild(statName)if not stat thenstat = setupStat(leaderstats, statName)endstat.Value = valueendreturn Leaderboard```
次のセクションでは、リーダーボードがどのように機能するかについて詳しく説明します。
リーダーボードを作成する
setupLeaderboard() 関数は、新しいフォルダーインスタンスを作成し、その名前を leaderstats とし、指定されたプレイヤーの子として設定します。Robloxは、leaderstats という名前のフォルダーを統計のコンテナとして自動的に認識し、統計を表示するためのUI要素を作成します。リーダーボードにある値は「値」オブジェクトとして保存する必要があります(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 スクリプト内でこれらを要求して、プレイヤーのコインデータを管理し表示します。
Update CoinServiceServerScriptService 内の既存の 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.Coinslocal coins = coinsFolder:GetChildren()local COIN_KEY_NAME = PlayerData.COIN_KEY_NAMElocal COOLDOWN = 10local COIN_AMOUNT_TO_ADD = 1local 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") thenlocal character = otherPart.Parentlocal player = Players:GetPlayerFromCharacter(character)if player then-- プレイヤーがコインに触れたcoin.Transparency = 1coin:SetAttribute("Enabled", false)updatePlayerCoins(player, function(oldCoinAmount)oldCoinAmount = oldCoinAmount or 0return oldCoinAmount + COIN_AMOUNT_TO_ADDend)task.wait(COOLDOWN)coin.Transparency = 0coin:SetAttribute("Enabled", true)endendend-- イベントリスナーを設定for _, coin in coins docoin: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 をクリックします。コインに向かって歩き、リーダーボードが隅に表示され、コインを収集するにつれてコインカウントが増えることを確認します。