スコア・データ初級Robux不要

Roblox Studioでコインを作る:触れるとScoreが増える方法

黄色いコインを3枚並べ、プレイヤーが触れるたびに1枚だけ消え、リーダーボードのScoreが0から3へ増える仕組みを作ろう。

公開日
3枚のコインを拾い終え、プレイヤー一覧のScoreが3になった画面

ゲーム内に黄色いコインを3枚置き、キャラクターが触れると1枚ずつ消えて、右上のScore0から3へ増えるようにする。完成までの目安は8分だ。この機能の実装にRobuxは必要ない。

3枚のコインを拾い終え、プレイヤー一覧のScoreが3になった画面

この記事は、リーダーボードへScoreを表示する記事の続きだ。Playしたときに自分の名前の横へScore = 0が出る状態から始めよう。Partの追加や複製をまだ迷う場合は、先にPart操作の記事を開いておくと進めやすい。

1. Coinsフォルダーへ3枚を作る

ExplorerのWorkspaceFolderを追加し、名前をCoinsにしよう。Folderは、複数の物を1か所へまとめる入れ物だ。今回は3枚のコインだけをまとめる。

Coinsの中へPartを1つ追加し、名前をCoin1にする。Propertiesで次の値を設定しよう。

Property
Shape Cylinder
Size 0.8, 4, 4
Orientation 0, 90, 0
Anchored オン
CanCollide オフ
CanTouch オン
Material Neon
Color Bright yellow

Coin1を2回複製してCoin2Coin3へ名前を変え、少し間隔を空けて並べる。位置や色はゲームに合わせて変えてよい。Scriptが必要とするのは、3枚がCoinsの中にあることだ。

黄色いコイン3枚とExplorerのCoinsフォルダー構成

並べるときは、SpawnLocationから歩いて届く同じ高さへ置こう。床へ半分埋まっていると見つけにくく、空中へ高く置きすぎるとジャンプしても触れない。まずは床から2〜3スタッドほど上へ置き、3枚の間をキャラクター1人分以上空けると変化を確認しやすい。

Tip — 通り抜けても「触れた」は分かる

CanCollideはキャラクターがPartへぶつかるか、CanTouchは触れた合図を受け取るかを決める。今回はCanCollide = falseCanTouch = trueなので、コインを通り抜けながら取得できる。

ここで一度Explorerを見直そう。Coinsと3枚の関係は次の形になる。

Workspace
└─ Coins
   ├─ Coin1
   ├─ Coin2
   └─ Coin3

Coin1Coinsを同じ階層へ置くのではなく、3枚すべてをFolderの中へ入れる。次に書くコードは、このFolderを開いて中にあるPartを順番に探す。

2. CoinCollectorを追加する

ExplorerのServerScriptServiceへScriptを追加し、CoinCollectorへ名前を変えよう。既存のLeaderboardは消さず、2本を並べる。

ServerScriptServiceのCoinCollectorと、3枚を管理するコード

CoinCollectorのコードをすべて消し、次へ置き換えよう。

local Players = game:GetService("Players")
local coinsFolder = workspace:WaitForChild("Coins")
local collected = {}

local function collectCoin(coin, otherPart)
	if collected[coin] then
		return
	end

	local character = otherPart:FindFirstAncestorOfClass("Model")
	local player = character and Players:GetPlayerFromCharacter(character)
	if not player then
		return
	end

	local leaderstats = player:FindFirstChild("leaderstats")
	local score = leaderstats and leaderstats:FindFirstChild("Score")
	if not score then
		return
	end

	collected[coin] = true
	score.Value += 1
	coin:Destroy()
end

for _, coin in coinsFolder:GetChildren() do
	if coin:IsA("BasePart") then
		coin.Touched:Connect(function(otherPart)
			collectCoin(coin, otherPart)
		end)
	end
end

Roblox公式のイベント解説にあるとおり、TouchedはPartへ何かが触れたときの合図だ。触れた手や足などがotherPartへ入り、そこからキャラクター全体を探す。

3枚それぞれへ同じ処理をつなぐ

最後のforから始まる部分は、Coinsの中身を1つずつ確認する。中身がPartなら、そのPartのTouchedcollectCoin()をつなぐ。3枚の中へ同じScriptを複製する必要はない。

workspace:WaitForChild("Coins")は、Coinsが読み込まれるまで待ってから次へ進む書き方だ。Folder名をCoincoinsへ変えると見つからないため、Explorerとコードの名前を同じにしよう。

触れた体から参加者を探す

otherPart:FindFirstAncestorOfClass("Model")は、触れた手や足から上へたどり、キャラクター全体のModelを探す。そのModelをPlayers:GetPlayerFromCharacter()へ渡すと、どの参加者の体だったかが分かる。

Tip — CharacterとPlayerは別の役割

Characterは画面内を歩く3Dの体、Playerは名前やScoreを持つ参加者のデータ側だ。GetPlayerFromCharacter()は、触れた体から対応する参加者を探す。NPCや落ちてきたPartならPlayerが見つからないため、何も増やさずに終わる。

Playerが見つかったら、leaderstatsの中からScoreを探す。どちらかがなければreturnでその接触だけを終える。コインのScriptが原因で、別の機能まで赤いエラーで止まるのを避けるためだ。

最初の接触だけを数える

キャラクターは手足など複数のPartでできているので、1枚へ触れただけでもTouchedが短時間に複数回届くことがある。コードは最初にcollected[coin] = trueを記録し、2回目以降を止める。その後でScoreを1増やし、Destroy()でそのPlay中のコインを消す。

この3行は順番を変えないようにしよう。

collected[coin] = true
score.Value += 1
coin:Destroy()

先に取得済みと記録してから数字を増やすため、ほぼ同時に2つの手足が触れても、後から来た処理は最初のifで止まる。Destroy()を先に置くと、その後の処理を追いにくくなるので、記事どおりの順番が確認しやすい。

迷ったら1枚目だけで途中確認する

3枚すべてを歩く前に、まずCoin1だけへ触れてみよう。Coin1が消え、右上がScore = 1になり、Coin2Coin3が残れば、Folder、Script、Scoreのつながりは動いている。

ここでScoreが0のままなら、残り2枚へ進んでも結果は変わらない。Stopして編集へ戻り、Coin1Coinsの中にあるか、CoinCollectorServerScriptServiceにあるかを先に直そう。1枚目が動いたあとで3枚を通し確認すると、どの段階で止まったかを見つけやすい。順番に確認しよう。

3. 3枚を順番に拾う

Playする前に、Explorerで次を確認しよう。

  • ServerScriptServiceLeaderboardCoinCollectorがある
  • Workspace > Coinsに3枚がある
  • 3枚ともAnchoredCanTouchがオン
  • コードのCoinsleaderstatsScoreの大文字小文字が一致している

Playを押し、Coin1からCoin3まで順番に歩いて触れよう。BasePart.Touchedの公式リファレンスどおり、接触した瞬間に接続した関数が動く。

キャラクターが3枚のコインへ順番に歩き、Scoreが0から3へ増える動き

次の4点が見えれば完成だ。

  1. 最初はコインが3枚あり、Scoreは0
  2. 1枚触れるたびに、そのコインだけが消える
  3. Scoreが1、2、3と1ずつ増える
  4. 3枚目のあと、コインは0枚でScoreは3

Stopすると、編集画面の3枚は元に戻る。もう一度PlayするとScoreも0から始まる。これは失敗ではなく、まだ前回の値を保存していないためだ。

2人で遊ぶとコインは共有される

CoinCollectorServerScriptServiceにあるため、3枚の状態は参加者全員で共有される。たとえばPlayer1がCoin1を取ると、そのコインはPlayer2の画面からも消え、増えるのはPlayer1のScoreだけだ。

1人ずつ別の3枚を用意する仕組みではない。みんなで先に取った人を競うゲームなら、この動きのままで使える。全員が同じコインを取れるようにする方法は別の目標になるため、この記事では扱わない。

増えない、または2以上増えるとき

  • Score自体がない: LeaderboardServerScriptServiceにあり、leaderstatsScoreの大文字小文字が記事どおりか確認する
  • コインが消えない: 3枚がWorkspace > Coinsの中にあり、CanTouchがオンか確認する
  • 触れても増えない: CoinCollectorLocalScriptではなく通常のScriptで作ったか確認する
  • 1枚で2以上増える: collected[coin] = truescore.Value += 1より前にあるか確認する
  • 赤いエラーが出る: Outputの最初の赤い行を開き、引用符、丸括弧、endの抜けを直してからStop、Playする

修正後はPlay中のまま試し続けず、いったんStopしてもう一度Playしよう。消えたコインとcollectedの記録が初期状態へ戻るため、3枚を同じ条件で確かめられる。

完成

これで、3枚のコインを全プレイヤーが共有し、最初に触れた人のScoreだけが1増えるようになった。次は、このScoreを退出後も残す。

次の記事ではData Storeでコイン数を保存する。

公式リファレンス

画像の拡大表示