前のチュートリアルでは、フェードするプラットフォームや致命的な溶岩など、さまざまなゲーム機能を作成しました。このチュートリアルでは、これらを組み合わせて、ユーザーが最も長く生き残ることができるかを競うプレイ可能なゲームを作成します。生存している間、毎秒ポイントがスコアに追加されます。
セットアップ
まず、ゲームのシーンを設定する必要があります。前のチュートリアルで作成したフェードするプラットフォームを複製し、ユーザーができるだけ長くプラットフォームのボードに留まることを競わせます。
また、致命的な溶岩を使用して、ユーザーがプラットフォームから落ちたときに殺すこともできますし、ただ彼らを運命に任せて落下させることもできます。ユーザーがプラットフォームにジャンプしてプレイを開始できるように、どこかにSpawnLocationを配置してください。

プレイヤーポイント
Robloxには、ユーザーの統計を表示するための組み込みのリーダーボードがあります。リーダーボードを通じてプレイヤーポイントを設定すると、ゲーム内の画面右側に表示されます。

後のチュートリアルでは、情報を表示するためのよりカスタマイズ可能な方法を学びますが、リーダーボードはRobloxで可視的なスコアリングシステムを作成する最も簡単な方法です。
ゲームの状態を設定するスクリプトはServerScriptServiceに配置するのが最適です。なぜなら、ゲームが開始されると自動的に実行されるからです。ServerScriptService内にSetupPointsという名前のスクリプトを作成します。

プレイヤーをリッスン
Robloxでは、サービスはさまざまな便利な機能を実行するオブジェクトです。Playersサービスには、ゲームに参加する各ユーザーのポイントを設定するために使用できるPlayerAddedというイベントがあります。
サービスには、GetService関数を使用してアクセスできます。この関数は、gameオブジェクト内で使用できます。gameは、ゲーム内のすべてを含むどこからでもアクセス可能な変数です。
game:GetService("Players")を使用してPlayersサービスの変数を作成します。
入力プレイヤーのパラメータを持つonPlayerAddedという関数を作成します。
onPlayerAdded関数をPlayerAddedイベントに接続します。
local Players = game:GetService("Players")local function onPlayerAdded(player)endPlayers.PlayerAdded:Connect(onPlayerAdded)
スタッツフォルダーを作成
ユーザーのポイントをリーダーボードに表示するには、Playerオブジェクト内に"leaderstats"という名前の新しいFolderを作成し、その中にポイントを入れるだけです。新しいオブジェクトは、スクリプト内でInstance.new()関数を介して作成できます。
Instance.new("Folder")を使用して新しいFolderオブジェクトを作成し、その結果をleaderstatsという新しい変数に格納します。
local function onPlayerAdded(player)local leaderstats = Instance.new("Folder")endleaderstatsのNameプロパティを"leaderstats"に設定します。
leaderstatsをplayerに親として設定します。
local Players = game:GetService("Players")local function onPlayerAdded(player)local leaderstats = Instance.new("Folder")leaderstats.Name = "leaderstats"leaderstats.Parent = playerendPlayers.PlayerAdded:Connect(onPlayerAdded)
ポイントを作成
リーダーボードシステムは、leaderstatsフォルダー内の任意の値を読み取り、見つけたものを表示します。
プレイヤーのポイントを追跡するための統計を追加するには、新しいIntValueオブジェクトをleaderstatsフォルダーに親として追加できます。値オブジェクトの名前は、その現在の値とともに表示されます。
- Nameを"Points"に設定します。
- Valueを0に設定します。これはリーダーボードがプレイヤーに対して最初に表示する値です。
- pointsオブジェクトをleaderstatsフォルダーに親として設定します。
local Players = game:GetService("Players")
local function onPlayerAdded(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local points = Instance.new("IntValue")
points.Name = "Points"
points.Value = 0
points.Parent = leaderstats
end
Players.PlayerAdded:Connect(onPlayerAdded)ゲームをテストすると、右上にユーザーの名前とその隣にポイントスコアが表示されたリーダーボードが表示されるはずです。
時間をカウント
各ユーザーは生存している間、毎秒ポイントを獲得する必要があります。whileループとtask.wait()関数を使用して、ポイントの値を毎秒更新できます。
- スクリプトの最後に、条件としてtrueを持つwhileループを作成します。
- ループ内で、task.wait()を1秒待機します。
Players.PlayerAdded:Connect(onPlayerAdded)
while true do
task.wait(1)
endプレイヤーリスト
ゲーム内のすべてのユーザーに対してコードを実行するには、GetPlayers関数によって返される配列を反復処理する必要があります。
配列は、順序で保存されたアイテムのリストです。各アイテムは、1から始まるインデックス位置でアクセスできます。配列の長さは、#を前に付けることで取得できます。
- Players:GetPlayers()の結果をplayerList変数に格納します。
- 開始値を1、終了値を#playerListとするforループを作成し、プレイヤーごとに1回のループの反復を取得します。
while true do
task.wait(1)
local playerList = Players:GetPlayers()
for currentPlayer = 1, #playerList do
-- playerList内の各プレイヤーに対するロジックをここに追加
end
endポイントを授与
forループ内で各ユーザーにポイントを授与するには、配列からユーザーを取得し、leaderstatsフォルダーに保存されているPointsオブジェクトに1を追加する必要があります。
配列に保存されたオブジェクトには角括弧を使用してアクセスします。たとえば、playerList配列の最初のアイテムにはplayerList[1]でアクセスできます。forループ内でplayerList[currentPlayer]と書くと、ループの各反復でリスト内の各ユーザーに移動できます。
- playerList[currentPlayer]のユーザーをplayerという変数に格納します。
- ユーザーのPointsオブジェクトをpointsという変数に格納します。
while true do
task.wait(1)
local playerList = Players:GetPlayers()
for currentPlayer = 1, #playerList do
local player = playerList[currentPlayer]
local points = player.leaderstats.Points
points.Value += 1
end
endゲームをテストすると、リーダーボードがプレイヤーのスコアを毎秒1ずつカウントアップして表示するはずです。
キャラクターをリッスン
ゲームの目的は、誰が最も長く生き残ることができるかを見ることですので、死んだユーザーのポイントは0にリセットする必要があります。
ユーザーが死んだときに検出するためには、そのユーザーのCharacterモデルを取得する必要があります。このモデルは、Playerオブジェクトがロードされた後にのみゲームに追加され、CharacterAddedイベントを使用してキャラクターが使用可能になるときにリッスンできます。onCharacterAddedという関数を作成し、キャラクター用のパラメータとプレイヤー用のパラメータを持たせます。
local Players = game:GetService("Players")
local function onCharacterAdded(character, player)
end
local function onPlayerAdded(player)
local leaderstats = Instance.new("Folder")onCharacterAdded関数のパラメータにユーザーを含めたにもかかわらず、実際のCharacterAddedイベントはキャラクターのみを返し、関連するユーザーは返しません。playerオブジェクトを渡すために、イベント接続のために匿名関数を使用します。
local function onPlayerAdded(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local points = Instance.new("IntValue")
points.Name = "Points"
points.Value = 0
points.Parent = leaderstats
player.CharacterAdded:Connect(function(character)
onCharacterAdded(character, player)
end)
endポイントをリセット
ユーザーが死ぬと、そのHumanoidは自動的にDiedイベントを発火します。このイベントを使用して、ポイントをリセットするタイミングを知ることができます。
HumanoidはCharacterモデル内にあり、そのモデルの内容はユーザーがスポーンする際にのみ組み立てられます。Humanoidオブジェクトがロードされるのを安全に待つために、WaitForChild()関数を使用します。この関数は、待機している子の名前を文字列として渡すことで、任意の親オブジェクトで呼び出すことができます。character:WaitForChild("Humanoid")を使用してHumanoidを待機する変数を作成します。
local Players = game:GetService("Players")
local function onCharacterAdded(character, player)
local humanoid = character:WaitForChild("Humanoid")
endDiedイベントに接続する必要がある関数は非常に短く、ここでのみ必要になるため、再び匿名関数を使用できます。
- HumanoidのDiedイベントに新しい匿名関数を接続します。
- 匿名関数内で、プレイヤーのPointsオブジェクトのための変数pointsを作成します。
local Players = game:GetService("Players")
local function onCharacterAdded(character, player)
local humanoid = character:WaitForChild("Humanoid")
humanoid.Died:Connect(function()
local points = player.leaderstats.Points
points.Value = 0
end)
endこれをテストすると、ユーザーのスコアが死んだときにリセットされるのがわかります。
プレイヤーを確認
ユーザーが死んでいる間もポイントを獲得し続けると、ゲームの精神に反するため、ポイントを授与する前にユーザーが生きているかどうかを確認する必要があります。
まず、onPlayerAdded関数内で、ユーザーが生きているかどうかを確認するために使用できる属性を定義する必要があります。この時点では、ユーザーはまだ生きておらず、スポーンしていません。なぜなら、キャラクターモデルがまだ追加される必要があるからです。
属性を使用すると、Roblox内のオブジェクトに独自のデータをカスタマイズできます。属性は名前と値で構成されます。SetAttribute関数を使用して、任意のオブジェクトに作成できます。playerに対してSetAttributeを呼び出して、"IsAlive"という新しい属性を値falseで作成します。
local function onPlayerAdded(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local points = Instance.new("IntValue")
points.Name = "Points"
points.Value = 0
points.Parent = leaderstats
player:SetAttribute("IsAlive", false)
player.CharacterAdded:Connect(function(character)
onCharacterAdded(character, player)
end)
endユーザーのキャラクターモデルが再スポーンすると、IsAliveの値をtrueに変更して、ユーザーが再びポイントを獲得できるようにする必要があります。
- onCharacterAdded内で、playerのIsAlive属性をtrueに設定します。
- onCharacterDied内で、playerのIsAlive属性をfalseに設定します。
local Players = game:GetService("Players")
local function onCharacterAdded(character, player)
player:SetAttribute("IsAlive", true)
local humanoid = character:WaitForChild("Humanoid")
humanoid.Died:Connect(function()
local points = player.leaderstats.Points
points.Value = 0
player:SetAttribute("IsAlive", false)
end)
end最後に、スクリプトの最後のwhileループでポイントが授与される前にIsAliveを確認する必要があります。GetAttribute関数は、属性の名前を受け取り、その値を返します。whileループ内で、ポイントを授与するコードをif文でラップし、条件をplayer:GetAttribute("IsAlive")にします。
while true do
task.wait(1)
local playerList = Players:GetPlayers()
for currentPlayer = 1, #playerList do
local player = playerList[currentPlayer]
if player:GetAttribute("IsAlive") then
local points = player.leaderstats.Points
points.Value += 1
end
end
end今すぐゲームをテストすると、ユーザーが生存している間は毎秒ポイントを獲得し、死んでいるときは0のままであることがわかります。友達と一緒にプレイして、誰が最高得点を獲得できるか見てみましょう。
これは始まりに過ぎません。ユーザーのためにゲームを改善し続けることができます。以下は幾つかのヒントです:
- すべてのプラットフォームのコードを1つのスクリプトにまとめて、更新をはるかに簡単にします。
- ユーザーがゲームエリアにテレポートされるのを待つロビーエリアを作成し、ユーザーが同時に開始できるようにします。
- 各ラウンドの勝者を発表します。
最終コード
local Players = game:GetService("Players")
local function onCharacterAdded(character, player)
player:SetAttribute("IsAlive", true)
local humanoid = character:WaitForChild("Humanoid")
humanoid.Died:Connect(function()
local points = player.leaderstats.Points
points.Value = 0
player:SetAttribute("IsAlive", false)
end)
end
local function onPlayerAdded(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local points = Instance.new("IntValue")
points.Name = "Points"
points.Value = 0
points.Parent = leaderstats
player:SetAttribute("IsAlive", false)
player.CharacterAdded:Connect(function(character)
onCharacterAdded(character, player)
end)
end
Players.PlayerAdded:Connect(onPlayerAdded)
while true do
task.wait(1)
local playerList = Players:GetPlayers()
for i = 1, #playerList do
local player = playerList[i]
if player:GetAttribute("IsAlive") then
local points = player.leaderstats.Points
points.Value += 1
end
end
end