🧟

【ロブロックス】生き残り時間の公式コードを読む

2025/02/09に公開

概要

ゲームを作るのに生き残り時間をスコアとして扱いたくて調べたら公式のコードと解説がありました
標準APIの勉強がてら読んでみます

https://create.roblox.com/docs/tutorials/use-case-tutorials/scripting/basic-scripting/score-points

公式のコード

やっていることの概略としては
1. プレイヤー参加時(onPlayerAdded)にプレイヤーごとのスコアを「リーダーボード」に表示するためのデータを作成
1. リーダーボード: ゲーム内プレイヤーなどの情報を表示するウィンドウ

  1. 毎秒、存在するPlayerの一覧を取得して、スコアを加算
  2. キャラクタースポーン時(CharacterAdded)にカウント開始
  3. キャラクターがタヒんだ時にスコアを0にする

下記のスクリプトを「ServerScriptService」の中に作成する

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 currentPlayer = 1, #playerList do
		local player = playerList[currentPlayer]
		local points = player.leaderstats.Points

		if player:GetAttribute("IsAlive") then
			local points = player.leaderstats.Points
			points.Value += 1
		end
	end
end

知見

ServerScriptService

ゲームのサーバー側で実行されるスクリプトを保管するための場所らしい
https://create.roblox.com/docs/reference/engine/classes/ServerScriptService

リーダーボード

標準で実装されてる各ユーザー毎に表示されるウィンドウ

ゲーム実行中にPlayersというオブジェクトが生成されている。
その中の各プレイヤーごとに「leadstats」という名前でフォルダを作成しその中に値のインスタンスを作るとリーダーボードに表示される。

Player と Character

Playerがゲームをプレイするユーザー
Characterがユーザーが操作するキャラ

上記のコードでは「Player」にスコアを紐づけてリーダーボードに表示するが、
スコアを0にする判定などは「Characer」がタヒんだ時に実行する

ので下記のようにキャラクタースポーン時のイベントに「player」を渡さなければいけない

local function onPlayerAdded(player)
    ~~~
	player.CharacterAdded:Connect(function(character)
		onCharacterAdded(character, player)
	end)
end

Players.PlayerAdded:Connect(onPlayerAdded)

若干分かり辛いがPkayerがゲーム開始時点のイベントでスコアを準備、同じ関数内でキャラクターへのイベントを登録している

playerが取得できないとCharacterAddedも呼び出せないので基本的な書き方なのかも

player:SetAttribute("IsAlive")

これは事前に用意されているものではなく実装側が任意につけてるフラグだった
humanoidのHealthで死亡判定せず、わざわざ別のフラグを使用しているのはCharactorではなくPlayerにスコアが紐づき、サーバーサイドで判定する必要があるからっぽい

Discussion