AIにたのんで、クリアタイムと「もう一度あそぶ」ボタンを足そう
動作確認日: 2026年10月20日(Roblox Studio 0.743)
連載「AIといっしょにゲームを作ろう」の、コインあつめゲームの4回めです。前の回(ゴールを足す)を読む
前の回で、コインを5つ全部取ると、ゴールが現れるようになりました。でも、クリアしたあとは、そこで終わりです。もう一度遊ぶには、いったん停止して、プレイし直さないといけません。
今回は、コインあつめゲームの仕上げです。クリアしたあとの部分を足します。
今回作るもの
- ゲームが始まってから、ゴールにさわるまでの時間をはかる
- クリアしたとき、「ゴール!クリア!」の下に「クリアタイム」を出す
- クリアしたとき、「もう一度あそぶ」ボタンを出す
- ボタンを押すと、コインもスコアもゴールも、最初の状態にもどって、スタート地点から遊び直せる
足すものが、4つあります。ふだんなら、一度にたのみすぎですが、全部「クリアしたあとの話」なので、ひとまとめにしました。
ChatGPTにたのむ
前の回までの作品を、スタジオで開いたまま、ChatGPTに次の文を送ります。
さっき作った「コインあつめダッシュ」を、仕上げてください。
今回は、クリアしたあとの部分を足します。
【作るもの】
1. ゲームが始まってから、ゴールにさわるまでの時間をはかる。
2. クリアしたとき、「ゴール!クリア!」の下に「クリアタイム: ○○.○秒」と出す。
3. クリアしたとき、「もう一度あそぶ」ボタンを出す。
4. そのボタンを押すと、コインが全部もどって、スコアも0にもどって、ゴールも見えなくなって、スタート地点から最初からやり直せる。
【ルール】
- 今までに作った足場、コイン、スコア表示、ゴールの見た目は、変えないでください。
- 名前は分かりやすくしてください(例:ClearTimeLabel、RetryButton)。
- 小学生が読めるように、スクリプトの中に日本語のコメントをつけてください。
- 音や、新しい面は、まだ作らないでください。
【最後にお願い】
作り終わったら、次の3つを、やさしい言葉で教えてください。
- 何を足したか
- 時間をはかっているのは、どのスクリプトのどこか
- 「もう一度あそぶ」を押したとき、何をもとにもどしているか
「もとにもどすもの」を、ひとつずつ書いたのが、今回の工夫です。「最初からやり直せるように」とだけ書くと、AIは、コインだけもどして、スコアをもどし忘れる、ということがあります。
できあがりを見る
約1分で、ChatGPTから返事が来ました。

返事を読むと、次のことがわかります。
- 足したもの:「ゴール!クリア!」の下に、「クリアタイム」と「もう一度あそぶ」ボタン
- 時間をはかるところ:RoundScriptのRoundStartTimeに、始まった時こくをおぼえます。ゴールにさわると、GoalScriptが、今の時こくから引いて、何秒かかったかを計算します
- ボタンでもとにもどすもの:コインを5つ、スコアを0、ゴールを見えない状態に。クリアの文字・タイム・ボタンを消して、プレイヤーをスタート地点にもどし、時間もはかり直します
「最後にお願い」の3つに、そのまま答えてくれています。「もう一度クリアできることも確認しました」という、AI自身が動作を確かめた報告も、ついてきました。
遊んでみる
- 画面の上の「▶(プレイ)」を押します
- 5つ全部のコインを取って、ゴールにさわります
- 「ゴール!クリア!」の下に、クリアタイムと、「もう一度あそぶ」ボタンが出ます

- 「もう一度あそぶ」を押します

スタート地点にもどって、左上は「コイン: 0 / 5」になり、足場の上のコインが、5つともどっています。ゴールは、また見えなくなりました。このあと、もう一度、ゴールまで遊べます。
問題なく動きました。 今回も、直してもらう必要はありませんでした。足すものが4つあっても、「もとにもどすもの」を書いておいたので、一度で動いたのかもしれません。
どこに増えたか見てみる
「■(停止)」を押して編集の画面にもどり、右のエクスプローラーを見てみましょう。今回は、新しい場所が3か所にあります。
- ServerStorageの中に、CoinTemplatesというフォルダがあります。中に、Coin1〜5が入っています。もどすためのコインの見本です
- ReplicatedStorageの中に、RetryRequestがあります。ボタンの知らせを運ぶ道具です
- StarterGuiのGoalGuiの中に、ClearTimeLabel(タイムの文字)とRetryButton(ボタン)と、RetryDisplayScriptが増えています
ServerStorageは、ゲームの中には出ない、しまっておく場所です。ReplicatedStorageは、画面の係とゲームの中身の係が、どちらも使える場所です。
スクリプトを読んでみる
今回は、新しいスクリプトが2つあり、前の回のGoalScriptも少し変わっています。流れを見てみましょう。
ボタンを押す(RetryDisplayScript)
↓ 「もう一度あそびたい!」と知らせる(RetryRequest)
やり直しの係(RoundScript)が、コイン・スコア・ゴール・場所・時間をもどす
1. 時間をはかる:RoundScript の前半と GoalScript
RoundScriptの前半です。
local function preparePlayer(player)
-- ゲームに入った時こくをおぼえて、時間をはかり始めるよ。
if player:GetAttribute("RoundStartTime") == nil then
player:SetAttribute("RoundStartTime", workspace:GetServerTimeNow())
player:SetAttribute("CoinCount", 0)
player:SetAttribute("GoalCleared", false)
end
end
Players.PlayerAdded:Connect(preparePlayer)
workspace:GetServerTimeNow():今の時こくです。時計のようなもので、時間がたつほど大きくなりますplayer:SetAttribute("RoundStartTime", ...):その人のスタートの時こくを、属性におぼえさせます。前の回で出てきたCoinCountと同じ、名前つきのメモですPlayers.PlayerAdded:Connect(preparePlayer):プレイヤーがゲームに入ったときに、この準備を動かします
つまり、はかり始めるのは、ゲームに入ったときからです。最初に動いたときではありません。
次に、GoalScriptの、ゴールにさわったところです。
-- 今の時こくから、スタートの時こくを引くと、かかった秒数になるよ。
local started = player:GetAttribute("RoundStartTime")
if not started then
return
end
player:SetAttribute("ClearTime", math.max(0, workspace:GetServerTimeNow() - started))
player:SetAttribute("GoalCleared", true)
workspace:GetServerTimeNow() - started:今の時こくから、スタートの時こくを引き算します。それが、かかった秒数です。たとえば、スタートが100秒、ゴールが109.4秒なら、109.4 - 100 = 9.4で、9.4秒ですmath.max(0, ...):0より小さくならないようにしますSetAttribute("ClearTime", ...):かかった秒数を、ClearTimeという名前でおぼえさせます。画面の係が、これを読んで、タイムを出します
2. タイムとボタンを見せる:RetryDisplayScript
StarterGuiのGoalGuiの中にある、RetryDisplayScriptです。
local function update()
local cleared = player:GetAttribute("GoalCleared") == true
local seconds = player:GetAttribute("ClearTime") or 0
-- 小数点のあとを1けたにして、秒数を見せるよ。
timeLabel.Text = string.format("クリアタイム: %.1f秒", seconds)
timeLabel.Visible = cleared
button.Visible = cleared
if not cleared then
waiting = false
end
end
string.format("クリアタイム: %.1f秒", seconds):文字の中の%.1fのところに、secondsの数を、小数点のあと1けたで入れます。9.4なら、「クリアタイム: 9.4秒」ですtimeLabel.Visible = clearedとbutton.Visible = cleared:クリアしている(true)ときだけ、タイムの文字とボタンを見せます。前の回の「ゴール!クリア!」と同じしくみです
3. ボタンを押したら:「知らせ」を送る
ここが、今回のいちばん新しいところです。同じスクリプトの、ボタンの部分です。
button.Activated:Connect(function()
-- ボタンを押したら、やり直しの係に知らせるよ。
if waiting then
return
end
waiting = true
retry:FireServer()
end)
button.Activated:Connect(function():ボタンが押されたときに動きますretry:FireServer():RetryRequestを使って、ゲームの中身の係(サーバー)に「もう一度あそびたい!」と知らせます。RemoteEvent(リモートイベント)という、知らせるための道具です
どうして、ボタンのスクリプトが、直接コインをもどさないのでしょうか。ボタンのスクリプトは、自分の画面だけを動かす、LocalScriptです。コインやゴールは、みんなで遊ぶゲームの中身なので、自分の画面だけでは、動かせないのです。そこで、お願いの手紙を出して、ゲームの中身の係に、やってもらいます。
4. もとにもどす:RoundScript の後半
手紙を受け取るのは、RoundScriptの後半です。
retry.OnServerEvent:Connect(function(player)
-- クリアした人だけ、やり直せるよ。続けて押しても大丈夫だよ。
if player:GetAttribute("GoalCleared") ~= true then
return
end
-- (中略:キャラクターを調べる)
player:SetAttribute("GoalCleared", false)
player:SetAttribute("CoinCount", 0)
player:SetAttribute("ClearTime", nil)
-- スタート地点にもどして、体の動きも止めるよ。
character:PivotTo(course.StartSpawn.CFrame + Vector3.new(0, 4, 0))
root.AssemblyLinearVelocity = Vector3.zero
root.AssemblyAngularVelocity = Vector3.zero
-- とっておいたコインのコピーで、5つとも元にもどすよ。
for i = 1, 5 do
local oldCoin = course:FindFirstChild("Coin" .. i)
if oldCoin then
oldCoin:Destroy()
end
templates:WaitForChild("Coin" .. i):Clone().Parent = course
end
-- 新しいスタートの時こくに入れかえるよ。
player:SetAttribute("RoundStartTime", workspace:GetServerTimeNow())
end)
retry.OnServerEvent:Connect(function(player):知らせが届いたときに、動きます。playerは、ボタンを押した人です- 最初の
if ... ~= true then return end:クリアしていない人が押しても、何もしないで終わります。ちょっとした安全のしかけです SetAttribute(...)の3行:GoalClearedをfalseに、CoinCountを0に、ClearTimeをnil(なし)に、もどします。すると、スコア表示も、ゴールも、クリアの文字も、前の回までのしくみで、自動でもどりますcharacter:PivotTo(...):キャラクターを、スタート地点の上に動かします。下の2行で、動いていた勢いも、止めますfor i = 1, 5 do ... end:1から5まで、くり返します。いま残っているコインがあれば、消して、CoinTemplatesの見本を、:Clone()(コピー)して、コースにならべ直します。コインが5つ、もどる部分です- 最後に、
RoundStartTimeを、新しいスタートの時こくにします。時間も、はかり直しです
「もとにもどす」ためには、もとの形を、とっておく必要があります。ChatGPTは、ServerStorageにコインの見本をしまっておいて、必要なときにコピーする、というやり方を選んでくれました。
ためしに、数字を変えてみましょう
クリアタイムの小数点の数は、RetryDisplayScriptの %.1f の1で決まっています。これを2に変えてみましょう。
- 「■(停止)」を押して、編集の画面にもどります
- エクスプローラーで、StarterGuiの中のGoalGuiを開いて、RetryDisplayScriptをダブルクリックします
string.format("クリアタイム: %.1f秒", seconds)の%.1fの1だけを、2に書きかえます(%.2fになります)- 「▶(プレイ)」を押して、ゴールまで遊びます
「クリアタイム: 9.43秒」のように、小数点のあとが2けたで出ます。 %.0f にすると、小数点なしの整数で出ます。確かめたら、2 を 1 にもどしておきましょう。
読めれば、直せます。 AIにたのまなくても、タイムの見え方を、自分で変えられました。
もっといい、たのみ方
- 「もとにもどすもの」を、ひとつずつ書く:コイン、スコア、ゴール、場所、時間のように、何をもとにもどしたいのかを書きます
- 「もどす」ために、何を残すかも聞く:今回は、AIがコインの見本をしまっておく、というやり方を選びました。「何をもとにもどしているか」と聞くと、そのしくみがわかります
- AIが確かめたことを、自分でも確かめる:「確認しました」と言われても、自分で遊んで、もう一度クリアできるかまで、見ておきましょう
つぎは
これで、コインあつめゲームが、完成しました。
足場にコインを置いて、スコアを出して、ゴールを作って、やり直せるようにする。この流れを、ChatGPTにたのみながら、1本のゲームとして作りました。次の回からは、2つめのゲームに進みます。
