「アスレチックのゲームを、最初から最後まで遊べる形で作りたい」「チュートリアルで1つずつ作れるようになったけれど、1本のゲームにまとめ方が分からない」
ロブロックス(Roblox)スタジオで、これまでの手順を組み合わせてアスレチックゲームを1本作る方法を、実際の画像付きで誰でも簡単に分かるように解説します。作るのは、夜の溶岩の上の足場を渡り、コインを集めてゴールを目指す「ナイトラン」です。前編では、舞台・コース・コイン・チェックポイント・ゴールまでを作ります。後編では、追いかけてくる敵、体力ゲージ、コインの保存、公開を足して完成させます。
中級ステップ27/28 前の記事:ロブロックス(Roblox)スタジオで家を作る方法 全体の順番を見る
使うもの:Roblox Studioが起動するパソコン、マウス、キーボード。1つずつの仕組みは、それぞれの記事でくわしく解説しています。この記事では、組み合わせ方と、つなぐところを中心に進めます。
今回の完成状態:下の画像のように、コースを渡ってゴールに乗ると「ゴール!おめでとう」が出て(画像の1)、右上に拾ったコインの数が出れば前編は完成です(画像の2)。

ゲームの設計図
1本のゲームにするときは、作り始める前に「どの記事の仕組みを、どこで使うか」を決めておくと迷いません。
| ゲームの部分 | 使う仕組み | くわしい記事 |
|---|---|---|
| 夜の舞台 | LightingのClockTime・OutdoorAmbient | 夜にする方法 |
| 足場と溶岩 | 部品をフォルダーにまとめる、触ると倒れる床 | オビーの作り方 |
| チェックポイント | SpawnLocationと、生き返る場所の記録 | チェックポイントの作り方 |
| コイン | 右上の数(leaderstats)、拾うと消えて戻る | コイン集めゲームの作り方 |
| ゴールのメッセージ | 画面に文字を出す(ScreenGui) | ボタンの作り方 |
| 後編:敵・体力・保存・公開 | 追う敵、体力ゲージ、DataStore、公開 | 後編で解説 |
部品は、役目ごとにフォルダーへまとめます。コースの部品は「Course」、コインは「Coins」に入れると、スクリプトがフォルダーの中をまとめて扱えます。
1. 作品をRobloxに保存する
後編でコインを保存する仕組み(DataStore)は、Robloxに保存した作品でないと試せません。最初に保存しておきます。
新しいBaseplateを開き、画面左上の「ファイル」を押して、「Robloxに保存」を押します(赤い枠)。ウィンドウの題名と作品のタブは、アカウント名が入るのでモザイクにしています。

保存の画面が開きます。「名前」の欄に作品の名前を入れ(画像の1)、「作成」を押します(画像の2)。ここでは「Asobishift Night Run」と入れました(画像は名前を入れる前の画面です)。

保存が終わると、作品のタブの名前が変わります(赤い枠)。保存しただけでは、ほかの人は遊べません。

保存の画面で「チーム制作機能」がオンのままだと、このあとの変更は自動でクラウドに保存されます。
2. 夜の舞台にする
エクスプローラの「Lighting」を押して選び、プロパティの検索欄に「ClockTime」と入力して、ClockTimeに「0」と入力します(赤い枠)。空が暗くなり、夜になります。

プロパティの検索欄に「OutdoorAmbient」と入力し、OutdoorAmbientに「120, 130, 180」と入力します(赤い枠)。夜のまま、床が見える明るさになります。くわしくは夜にする方法で解説しています。

3. コースのフォルダーを作る
エクスプローラの「Workspace」にマウスを乗せて、右に出る「+」を押します(赤い枠)。

一覧の検索欄に「Folder」と入れて「Folder」を押すと、Workspaceの中にFolderが入ります(赤い枠)。

エクスプローラで「Folder」を押して選び、F2キーを押して名前を「Course」に変えます(赤い枠)。

エクスプローラの「SpawnLocation」(最初からあるスタート地点)を、マウスで押したまま「Course」の上まで動かして離します。CourseのFolderの中に(画像の1)、SpawnLocationが入ります(画像の2)。

4. 足場を4つ並べる
エクスプローラの「Course」にマウスを乗せて、右に出る「+」を押します(赤い枠)。

一覧の検索欄に「Part」と入れ、一覧の「Part」を押します(赤い枠)。

Courseの中にPartが入ります。エクスプローラで「Part」を押して選び、F2キーを押して名前を「Platform1」に変えます(赤い枠)。

プロパティの検索欄に「Size」と入力し、Sizeに「6, 1, 6」と入力します(赤い枠)。

プロパティの検索欄に「Position」と入力し、CFrameの中のPositionに「0, 3, -14」と入力します(赤い枠)。

プロパティの検索欄に「Color」と入力し、Colorに「70, 130, 230」と入力します(赤い枠)。

プロパティの検索欄に「Anchored」と入力し、Anchoredにチェックを入れます(赤い枠)。

エクスプローラで「Platform1」を押して選び、Ctrl + Dキーを押すと、同じ設定の足場がもう1つできます(赤い枠)。

2つ目の名前をF2キーで「Platform2」に変え、CFrameの中のPositionに「0, 5, -25」と入力します(画像の1)。2つ目の足場が奥の少し高い所に移ります(画像の2)。

同じように、Platform1を複製して名前とPositionを変え、足場を4つにします。
| 名前 | Position | ゲームの中での場所 |
|---|---|---|
| Platform1 | 0, 3, -14 | スタートのすぐ先 |
| Platform2 | 0, 5, -25 | 1段上がる |
| Platform3 | 0, 7, -36 | もう1段上がる |
| Platform4 | 0, 7, -62 | チェックポイント1の先 |
足場が4つ並びます(画像の1・2)。足場どうしのすき間は5スタッドで、ジャンプで届く幅にしています。

5. 落ちたら倒れる溶岩を置く
エクスプローラの「Course」の「+」から、もう1つ「Part」を入れます(赤い枠)。

エクスプローラで名前を「Lava」に変えます(赤い枠)。

プロパティの検索欄に「Size」と入力し、Sizeに「40, 1, 88」と入力します(赤い枠)。コース全体の下に敷く大きな床です。

プロパティの検索欄に「Position」と入力し、CFrameの中のPositionに「0, 0.6, -51」と入力します(赤い枠)。地面より少しだけ上に置くので、足場から落ちると必ず溶岩に触れます。溶岩の手前の端は、スタートの台(SpawnLocation)の1スタッド先で止まるので、スタートの台の上に立っている間は溶岩に触れません。

プロパティの検索欄に「Color」と入力し、Colorに「255, 80, 30」と入力します(赤い枠)。

プロパティの検索欄に「Material」と入力し、Materialを「Neon」にします(赤い枠)。夜の中で溶岩が光って見えます。

プロパティの検索欄に「Anchored」と入力し、Anchoredにチェックを入れます(赤い枠)。

6. チェックポイントを2つ置く
エクスプローラの「Course」の「+」を押し、一覧の検索欄に「SpawnLocation」と入れて、一覧の「SpawnLocation」を押します(赤い枠)。

Courseの中に2つ目の「SpawnLocation」が入ります(赤い枠)。

新しく入ったほうの名前を「Checkpoint1」に変えます(赤い枠)。

プロパティの検索欄に「Size」と入力し、Sizeに「8, 1, 8」と入力します(赤い枠)。

プロパティの検索欄に「Position」と入力し、CFrameの中のPositionに「0, 7.5, -49」と入力します(赤い枠)。Platform3とPlatform4の間に入ります。

エクスプローラで「Checkpoint1」を選び、Ctrl + Dキーで複製します(赤い枠)。

複製したほうの名前を「Checkpoint2」に変えます(赤い枠)。

プロパティの検索欄に「Position」と入力し、CFrameの中のPositionに「0, 9.5, -73」と入力します(赤い枠)。Platform4の先、ゴールの手前に入ります。

最後に、最初からあった「SpawnLocation」の名前を「StartSpawn」に変えます(赤い枠)。スクリプトで、スタート地点をこの名前で探すためです。

7. ゴールを置く
エクスプローラの「Course」の「+」から「Part」を入れます(赤い枠)。

名前を「Goal」に変えます(赤い枠)。

プロパティの検索欄に「Size」と入力し、Sizeに「8, 1, 8」と入力します(赤い枠)。

プロパティの検索欄に「Position」と入力し、CFrameの中のPositionに「0, 11, -86」と入力します(赤い枠)。コースのいちばん奥、いちばん高い所です。

プロパティの検索欄に「Color」と入力し、Colorに「255, 210, 60」と入力します(赤い枠)。

プロパティの検索欄に「Material」と入力し、Materialを「Neon」にします(赤い枠)。夜のコースの先で、ゴールが光って見えます。

プロパティの検索欄に「Anchored」と入力し、Anchoredにチェックを入れます(赤い枠)。

8. コインを3枚置く
エクスプローラの「Course」の左の「▼」を押して閉じます。「Workspace」の「+」から「Folder」を入れます(赤い枠)。

名前を「Coins」に変えます(赤い枠)。

エクスプローラの「Coins」にマウスを乗せて、右に出る「+」を押します(赤い枠)。

一覧の検索欄に「Part」と入れ、一覧の「Part」を押します(赤い枠)。

Coinsの中に入ったPartの名前を「Coin」に変えます(赤い枠)。

プロパティの検索欄に「Shape」と入力し、Shapeを「Cylinder」にします(赤い枠)。

プロパティの検索欄に「Size」と入力し、Sizeに「0.4, 2.5, 2.5」と入力します(赤い枠)。うすい円盤になります。

プロパティの検索欄に「Position」と入力し、CFrameの中のPositionに「0, 6, -14」と入力します(赤い枠)。Platform1の上に浮かびます。

プロパティの検索欄に「Color」と入力し、Colorに「255, 200, 0」と入力します(赤い枠)。

プロパティの検索欄に「Material」と入力し、Materialを「Neon」にします(赤い枠)。

プロパティの検索欄に「Anchored」と入力し、Anchoredにチェックを入れます(赤い枠)。

プロパティの検索欄に「CanCollide」と入力し、CanCollideのチェックを外します(赤い枠)。コインにぶつかって止まらず、通り抜けながら拾えます。

Coinを2回複製し、Positionを「0, 10, -36」(Platform3の上)と「0, 10, -62」(Platform4の上)に変えます。名前は3つとも「Coin」のままで大丈夫です。足場の上に、コインが3枚光ります(赤い枠)。

9. コースのスクリプトを入れる
エクスプローラの「Workspace」の左の「▼」を押して閉じます。「ServerScriptService」にマウスを乗せて、右に出る「+」を押します(赤い枠)。

一覧の検索欄に「Script」と入れ、一覧の「Script」を押します(赤い枠)。

名前を「CourseService」に変えます(赤い枠)。

開いているCourseServiceの画面で、中身を全部消して、次のコードを貼り付けます。オビーの溶岩とゴールの仕組みと、チェックポイントの仕組みを、1つのスクリプトにまとめたものです。
local Players = game:GetService("Players")
local course = workspace:WaitForChild("Course")
local start = course:WaitForChild("StartSpawn")
local lava = course:WaitForChild("Lava")
local goal = course:WaitForChild("Goal")
local checkpoints = {
course:WaitForChild("Checkpoint1"),
course:WaitForChild("Checkpoint2"),
}
-- 触った物から、生きているプレイヤーを探す
local function getPlayer(hit)
local character = hit:FindFirstAncestorOfClass("Model")
local player = character and Players:GetPlayerFromCharacter(character)
local humanoid = character and character:FindFirstChildOfClass("Humanoid")
if player and humanoid and humanoid.Health > 0 then
return player, humanoid
end
end
-- 入ってきた人を、スタートから始める
local function setup(player)
player.RespawnLocation = start
player:SetAttribute("Stage", 0)
player:SetAttribute("Cleared", false)
end
Players.PlayerAdded:Connect(setup)
for _, player in Players:GetPlayers() do
setup(player)
end
-- 溶岩に触れたら倒れる(チェックポイントから生き返る)
lava.Touched:Connect(function(hit)
local player, humanoid = getPlayer(hit)
if player then
humanoid.Health = 0
end
end)
-- チェックポイントは、順番どおりに触ったときだけ記録する
for index, point in checkpoints do
point.Touched:Connect(function(hit)
local player = getPlayer(hit)
if player and player:GetAttribute("Stage") == index - 1 then
player:SetAttribute("Stage", index)
player.RespawnLocation = point
end
end)
end
-- ゴールに触ったら、ゴールした印を付ける
goal.Touched:Connect(function(hit)
local player = getPlayer(hit)
if player and not player:GetAttribute("Cleared") then
player:SetAttribute("Cleared", true)
print(player.Name .. " がゴールしました")
end
end)

| まとめた仕組み | コードの場所 | していること |
|---|---|---|
| スタート地点 | setup | 入ってきた人の生き返る場所(RespawnLocation)をStartSpawnにする |
| 溶岩 | lava.Touched | 触った人の体力を0にする |
| チェックポイント | for index, point in checkpoints | 1→2の順に触ったときだけ、生き返る場所を変える |
| ゴール | goal.Touched | 「Cleared」という印(属性)を付ける。画面の文字は12章のLocalScriptが出す |
チェックポイントの「順番どおり」の確かめがあるので、Checkpoint2に先に触っても記録されません。
10. コインのスクリプトを入れる
もう一度「ServerScriptService」の「+」から「Script」を入れ、名前を「CoinService」に変えます(赤い枠)。

開いているCoinServiceの画面で、中身を全部消して、次のコードを貼り付けます。コイン集めゲームと同じ仕組みです。
local Players = game:GetService("Players")
local coins = workspace:WaitForChild("Coins")
local RESPAWN_SECONDS = 5 -- 拾われたコインが戻るまでの秒数
-- 参加した人ごとに、右上の Coins を用意する
local function addLeaderstats(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local count = Instance.new("IntValue")
count.Name = "Coins"
count.Value = 0
count.Parent = leaderstats
end
Players.PlayerAdded:Connect(addLeaderstats)
for _, player in Players:GetPlayers() do
addLeaderstats(player)
end
local function setupCoin(coin)
local ready = true
coin.Touched:Connect(function(hit)
if not ready then
return
end
local player = Players:GetPlayerFromCharacter(hit.Parent)
if not player then
return
end
ready = false
player.leaderstats.Coins.Value += 1
coin.Transparency = 1
task.wait(RESPAWN_SECONDS)
coin.Transparency = 0
ready = true
end)
end
for _, coin in coins:GetChildren() do
setupCoin(coin)
end

コースとコインのスクリプトを分けておくと、あとで「コインだけ直したい」ときに、見るスクリプトが1つで済みます。後編では、このCoinServiceにコインの保存を足します。
11. ゴールのメッセージの文字を作る
エクスプローラの「ServerScriptService」の左の「▼」を押して閉じます。「StarterGui」にマウスを乗せて、右に出る「+」を押します(赤い枠)。

一覧の検索欄に「ScreenGui」と入れて「ScreenGui」を押します。StarterGuiの中にScreenGuiが入ります(赤い枠)。

名前を「GoalGui」に変えます(赤い枠)。

「GoalGui」の「+」から、一覧の検索欄に「TextLabel」と入れて「TextLabel」を押します(赤い枠)。

名前を「Message」に変えます(赤い枠)。

Messageのプロパティを、1つずつ変えます。
プロパティの検索欄に「AnchorPoint」と入力し、AnchorPointに「0.5, 0」と入力します(赤い枠)。

プロパティの検索欄に「Position」と入力し、Positionに「0.5, 0, 0.15, 0」と入力します(赤い枠)。画面の上の真ん中に移ります。

プロパティの検索欄に「Size」と入力し、Sizeに「0, 360, 0, 60」と入力します(赤い枠)。

プロパティの検索欄に「Text」と入力し、Textに「ゴール!おめでとう」と入力します(画像の1)。四角の中に文字が出ます(画像の2)。

プロパティの検索欄に「TextScaled」と入力し、TextScaledにチェックを入れます(赤い枠)。文字が四角に合わせて大きくなります。

プロパティの検索欄に「Visible」と入力し、Visibleのチェックを外します(赤い枠)。ゲームが始まったときは見えないようにして、ゴールしたときだけスクリプトで見せます。

12. ゴールしたときに文字を出すスクリプトを入れる
「GoalGui」の「+」から、一覧の検索欄に「LocalScript」と入れて「LocalScript」を押します(赤い枠)。

名前を「GoalMessage」に変えます(赤い枠)。

開いているGoalMessageの画面で、中身を全部消して、次のコードを貼り付けます。
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local label = script.Parent:WaitForChild("Message")
-- ゴールした印が付いたら、メッセージを出す
local function update()
label.Visible = player:GetAttribute("Cleared") == true
end
player:GetAttributeChangedSignal("Cleared"):Connect(update)
update()

サーバーのCourseServiceが付けた「Cleared」の印を、プレイヤー側のGoalMessageが見て、文字を出します。サーバーが決めて、画面はプレイヤー側で出すのは、RemoteEventの使い方でも出てきた、Robloxのゲームの基本の分け方です。
13. テストで最初から最後まで遊ぶ
3D画面の上の作品のタブを押して3D画面に戻り、F5キーでテストを始めます。スタート地点から始まり(画像の1)、右上のCoinsは0です(画像の2)。
右上の名前の欄はモザイクにしています。

Platform1に飛び乗ってコインに触ると、コインが消えて(画像の1)、Coinsが1になります(画像の2)。

足場を渡って、Checkpoint1に乗ります(赤い枠)。ここで生き返る場所が記録されます。

足場から落ちて溶岩に触れると、キャラクターが倒れます(赤い枠)。画像では、倒れた体が近くの足場の上に乗っています。

少しすると、スタート地点ではなく、Checkpoint1から生き返ります(赤い枠)。生き返った直後は、まわりに青い守りの光が出ます。

最後の足場とCheckpoint2を渡って、ゴールに乗ると「ゴール!おめでとう」が出ます(画像の1)。3枚とも拾っていれば、Coinsは3です(画像の2)。

| 試したこと | 結果 |
|---|---|
| テストを始める | StartSpawnから始まり、Coinsは0 |
| コインに触る | コインが消えてCoinsが1増え、5秒後にコインが戻る |
| Checkpoint1に乗ってから溶岩に落ちる | Checkpoint1から生き返った |
| ゴールに乗る | 「ゴール!おめでとう」が出て、出力に「〇〇 がゴールしました」 |
確かめ終わったら、Shift + F5キーでテストを停止します。
コースを自分らしく変える
表の「足場のPosition」や「MessageのText」は、エクスプローラでその部品を押して選び、プロパティの検索欄にPositionやTextと入力して、右の欄を変えます。Positionは「▼CFrame」のすぐ下の欄です。
| 変えたいこと | 変える場所 | 例 |
|---|---|---|
| 足場を増やす | Platform1をCtrl + Dで複製 | Positionを1つずつずらす。スクリプトは直さない |
| ジャンプを難しくする | 足場のPosition | すき間を5スタッドから7スタッドに広げる |
| チェックポイントを増やす | Checkpoint1を複製し、CourseServiceの checkpoints に1行足す | course:WaitForChild("Checkpoint3"), |
| コインを増やす | Coinを複製 | 名前は「Coin」のままでよい。CoinServiceはフォルダーの中を全部扱う |
| ゴールの文字 | MessageのText | 「クリア!」など |
アシスタントに頼むときは、部品の名前とフォルダーを書くと、思ったとおりに足してもらいやすくなります。
Roblox Studioで、Workspaceの「Course」フォルダーの中に、Platform1〜4とCheckpoint1・2、Lava、Goalがあります。
Platform4とCheckpoint2の間に、左右にゆっくり動く足場を1つ足してください。
足場はCourseフォルダーに入れ、TweenServiceで動かしてください。
動かないときの確かめ方
| 症状 | 見るところ | 直し方 |
|---|---|---|
| 溶岩に落ちても倒れない | 名前 | CourseフォルダーとLavaの名前が合っているか。CourseServiceがServerScriptServiceにあるか |
| スタート地点から生き返ってしまう | チェックポイントの順番 | Checkpoint1に触ってから落ちたか。Checkpoint1・2がSpawnLocationか |
| Coinsが右上に出ない | CoinService | ServerScriptServiceにあるか。CoinsフォルダーにCoinが入っているか |
| ゴールの文字が出ない | GoalGui | MessageとGoalMessageがGoalGuiの中にあり、名前が合っているか |
| 出力に「Infinite yield possible」と出る | 名前 | 出力に書かれた名前の部品があるか。この表示の読み方はInfinite yield possibleの直し方で解説しています |
よくある質問
前編の作品は、ほかの人に遊んでもらえる?
この記事では、作品をRobloxに保存しただけで、公開はしていません。後編で敵と体力を足してから、公開の手順を解説します。先に公開したいときは、テストと公開の方法を見てください。
「ファイル」→「Robloxに保存」をもう一度押したら「公開」の画面が出た
アソビシフト編集部が試したときは、2回目に「Robloxに保存」を押すと「バージョンノートと一緒に公開」という画面が出ました。チーム制作がオンのときは、変更が自動でクラウドに保存されるので、この画面は「キャンセル」で閉じて大丈夫です。
次のステップ(中級 28/28)
次は、敵・体力・回復・ダッシュ・コインの保存・効果音を足して、アスレチックゲームを完成させます(後編)。
次に知りたいことを選ぶ
- 次のステップ:敵・体力・回復・ダッシュ・コインの保存・効果音を足して、アスレチックゲームを完成させます(後編) → ロブロックス(Roblox)のアスレチックゲームの作り方【後編】
- オビーの仕組みをくわしく知りたい → ロブロックス(Roblox)でオビーを作る方法
- チェックポイントをくわしく知りたい → ロブロックス(Roblox)でチェックポイントを作る方法
- 夜の明るさを調整したい → ロブロックス(Roblox)スタジオで夜にする方法