「ロブロックスのスクリプトはLua言語と聞いたけれど、if・for以外の書き方が分からない」「AIが書いたコードのelseifやwhile、pairsが読めない」
ロブロックス(Roblox)のスクリプトで使うLua言語の基本を、実際の画像付きで誰でも簡単に分かるように解説します。ここでは、30秒のあいだに赤い床を何回踏めたかで、看板のランクと色が変わる仕組みを作ります。1つのスクリプトの中で、if・elseif・else、return、文字をつなぐ「..」、配列、辞書、whileを使います。
中級ステップ25/28 前の記事:ロブロックス(Roblox)スクリプトの読み方 全体の順番を見る
使うもの:Roblox Studioが起動するパソコン、マウス、キーボード。変数・テーブル・関数・for・if・イベントの読み方は、前の記事のスクリプトの読み方で解説しています。この記事はその続きです。
今回の完成状態:下の画像のように、30秒たつと看板に「おわり!」と最後のスコアとランクが出れば成功です。10回以上踏むと、看板は金色の「ランク Gold」になります(赤い枠)。

この記事で覚える書き方
| 書き方 | 見た目 | ひとことで言うと |
|---|---|---|
| elseif・else | if 条件 then … elseif 条件 then … else … end | 上から順に調べて、最初に合った1つだけを動かす |
| 比べる記号 | >= == ~= | 数や文字を比べて、合っているか(true)合っていないか(false)を決める |
| return | return "Gold" | 関数の答えを返す |
| .. | "スコア " .. score | 文字と文字(数)をつなぐ |
| 配列 | { 赤, 青 } と table.insert | 順番に並べた入れ物。後ろに足せる |
| 辞書 | { Gold = 金色 } | 名前(キー)で中身を取り出す入れ物 |
| ipairs・pairs | for i, v in ipairs(…) | 配列・辞書の中身を1つずつ取り出す |
| while | while 条件 do … end | 条件に合うあいだ、くり返す |
Robloxのスクリプトの言語は、正しくはLuau(ルーアウ)といいます。Lua 5.1をもとにRobloxが作った言語で、書き方はほとんど同じです。
1. 踏む床を置く
新しいBaseplateを開きます。エクスプローラの「Workspace」にマウスを乗せて、右に出る「+」(赤い枠)を押します。

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

エクスプローラに入った「Part」を押して選び、F2キーを押して名前を「ScorePad」に変えます(赤い枠)。

続けてScorePadを選んだまま、次の4つを変えます。どれもプロパティの検索欄に名前を入力してから変えます。PositionはCFrameのすぐ下の欄に入れます。
| プロパティ | 入れる値 | 画像 |
|---|---|---|
| Size | 6, 1, 6 | 下の1枚目 |
| Position | 0, 0.5, -12 | 下の2枚目(スポーン地点の前に置く) |
| Color | 255, 80, 80 | 下の3枚目(赤) |
| Anchored | チェックを入れる(上の「固定」を押しても入る) | 下の4枚目 |
2. 点数を出す看板を置く
点数を出す看板は、消える床と時限の橋の記事の手順7「残り秒数を出す板を作る」と同じ作り方ですが、同記事の「TimerDisplay」を、ここでは「ScoreBoard」と読みかえてください。
まず看板の板を置きます。手順1と同じように、エクスプローラの「Workspace」にマウスを乗せて「+」を押し、検索欄に「Part」と入力して、一覧の「Part」を押します。
エクスプローラに入った「Part」を押して選び、F2キーを押して名前を「ScoreBoard」に変えます。
続けてScoreBoardを選んだまま、次の4つを変えます。どれもプロパティの検索欄に名前を入力してから変えます。PositionはCFrameのすぐ下の欄に入れます。
| プロパティ | 入れる値 |
|---|---|
| Size | 10, 6, 1 |
| Position | 0, 5, -20(床の奥に立てる) |
| Color | 40, 40, 50(黒に近い灰色) |
| Anchored | チェックを入れる(上の「固定」を押しても入る) |
次に、板に文字を出す部品を入れます。
- エクスプローラの「ScoreBoard」にマウスを乗せて「+」を押し、検索欄に「SurfaceGui」と入力して、一覧の「SurfaceGui」を押します
- SurfaceGuiを選んだまま、プロパティの検索欄に「Face」と入力し、Faceの一覧から「Back」を選びます。最初の「Front」のままだと、スポーン地点から見えない裏側の面に文字が貼られます
- エクスプローラの「SurfaceGui」にマウスを乗せて「+」を押し、検索欄に「TextLabel」と入力して、一覧の「TextLabel」を押します
- TextLabelを選んだまま、プロパティでSizeを「{1, 0},{1, 0}」にし、TextScaledにチェックを入れ、Textの欄の「Label」を消して空にします
床の奥に看板(画像の1)が立ち、エクスプローラにScoreBoard(画像の2)が入れば準備はできています。

3. スクリプトを入れる
エクスプローラの「ScorePad」にマウスを乗せて「+」を押し、検索欄に「Script」と入力して、一覧の「Script」(赤い枠)を押します。

ScorePadの中に入った「Script」を押して選び、F2キーを押して名前を「ScorePadScript」に変えます(赤い枠)。

続けてScorePadScriptを選んだまま、プロパティの検索欄に「RunContext」と入力し、「▼動作」の欄にあるRunContextの一覧から「Server」を選びます(赤い枠)。

スクリプトの画面の中身を全部消して、次のコードを貼り付けます。
-- 30秒のあいだに踏んだ回数でランクが決まる床(ScorePad の中の Script「ScorePadScript」)
local pad = script.Parent
local boardText = workspace.ScoreBoard.SurfaceGui.TextLabel
local score = 0 -- 踏んだ回数
local timeLeft = 30 -- のこりの秒数
local playing = true -- 遊べる時間の途中かどうか(true か false)
local busy = false -- 1回分の処理の途中かどうか
-- 配列:順番に並べた色。table.insert で後ろに1つ足す
local padColors = {
Color3.fromRGB(255, 80, 80),
Color3.fromRGB(80, 200, 255),
}
table.insert(padColors, Color3.fromRGB(255, 220, 80))
-- 辞書:名前(キー)で値を取り出すテーブル
local rankColors = {
Gold = Color3.fromRGB(255, 200, 40),
Silver = Color3.fromRGB(200, 200, 210),
Bronze = Color3.fromRGB(205, 127, 50),
None = Color3.fromRGB(255, 255, 255),
}
-- 点数からランクを決めて、return で返す
local function getRank(points)
if points >= 10 then
return "Gold"
elseif points >= 5 then
return "Silver"
elseif points >= 1 then
return "Bronze"
else
return "None"
end
end
-- 看板の文字と色を、今の点数に合わせて書きかえる
local function showBoard()
local rank = getRank(score)
boardText.Text = "スコア " .. score .. "\nランク " .. rank .. "\nのこり " .. timeLeft .. "秒"
boardText.BackgroundColor3 = rankColors[rank]
end
-- 始める前に、配列と辞書の中身を出力に出す
for i, color in ipairs(padColors) do
print("床の色", i, color)
end
for name, color in pairs(rankColors) do
print("ランクの色", name, color)
end
pad.Touched:Connect(function(hit)
local humanoid = hit.Parent:FindFirstChildWhichIsA("Humanoid")
if humanoid and playing and not busy then
busy = true
score += 1
-- 踏むたびに、配列の色を順番に使う
pad.Color = padColors[(score - 1) % #padColors + 1]
showBoard()
task.wait(0.3)
busy = false
end
end)
-- while:のこりの秒数が0より大きいあいだ、くり返す
showBoard()
while timeLeft > 0 do
task.wait(1)
timeLeft -= 1
showBoard()
end
playing = false
boardText.Text = "おわり!\nスコア " .. score .. "\nランク " .. getRank(score)

4. テストで、ランクが変わるか確かめる
3D画面の上の作品のタブ「Place1」を押して3D画面に戻り、F5キーでテストを始めます(タブの名前はパソコンによって違います)。のこりの30秒は、テストを始めたときから数え始めます。アバターが出てくるまでに、もう数秒減っています。
テストが始まると、出力に「床の色」が3行、「ランクの色」が4行出ます(赤い枠)。ほかのメッセージに混ざって見えにくいときは、出力の右上の「フィルタ」の欄に「色」と入力すると、この7行だけが残ります。色は「1, 0.313726, 0.313726」のように0〜1の数で出ます。255を1として表した数なので、コードの「255, 80, 80」と同じ色です。

床に乗ったり降りたりして、何度も踏みます。踏むたびに床の色が変わり、看板のスコアが増えます。スコアが3のときは、看板が銅色で「ランク Bronze」でした(赤い枠)。

スコアが5以上になると、看板が銀色(明るい灰色)の「ランク Silver」に変わります(赤い枠)。

10以上になると金色の「ランク Gold」になりました(赤い枠)。

のこりが0秒になると、看板に「おわり!」と最後のスコアが出ます(赤い枠)。おわりのあとに床を3回踏んでも、スコアは12のまま増えませんでした。

Shift + F5キーでテストを停止します。
5. 書き方を1つずつ読む
if・elseif・else:上から順に調べて、最初に合った1つだけ
if points >= 10 then
return "Gold"
elseif points >= 5 then
return "Silver"
elseif points >= 1 then
return "Bronze"
else
return "None"
end
ifは上の条件から順に調べます。最初に合った1つだけを動かし、残りは調べません。点数が11のときは、1つ目の points >= 10 に合うので「Gold」になり、その下の >= 5 は見ません。どれにも合わないときは、elseの中が動きます。
順番を逆にして >= 1 を一番上に書くと、11点でも「Bronze」になってしまいます。大きい数の条件から先に書くのがコツです。elseの後ろにはthenを付けません。
比べる記号
| 記号 | 意味 | 例 |
|---|---|---|
== | 同じ | rank == "Gold" |
~= | 同じではない | rank ~= "None" |
> < | より大きい・より小さい | timeLeft > 0 |
>= <= | 以上・以下 | points >= 10 |
=(1つ)は「入れる」、==(2つ)は「同じか比べる」です。ifの条件に = を1つだけ書くと、比べる文として読めずにエラーになります。Robloxの公式チュートリアルにも、まちがえやすい点として注意が書かれています。
return:関数の答えを返す
getRankは点数を受け取ってランクの名前を返す関数です。local rank = getRank(score) と書くと、returnで返した「Gold」などがrankに入ります。returnが動くと、関数はそこで終わります。
.. と \n:文字をつなぐ・改行する
boardText.Text = "スコア " .. score .. "\nランク " .. rank
.. は文字と文字をつなぐ記号です。scoreのような数をつなぐと、数は自動で文字になります。\n は改行です。コードの看板の文字は \n が2つあるので、スコア・ランク・のこりの3行に分かれます。
コマンドバーで「..」を試す
コードを書きかえずに1行だけ試したいときは、コマンドバーを使います。コマンドバーは、Studioの画面のいちばん下にある「Ctrl↵でコマンドを実行するか…」と書かれた細長い欄(赤い枠)です。

コマンドバーを押して、次の1行を入力し、Ctrl+Enterキーを押します。print は、かっこの中を出力に出す命令です。
print("スコア " .. 5)
コマンドバーに入れた1行(画像の1)が動き、出力に「スコア 5」(画像の2)と出ました。文字の「スコア 」と数の5が、1つの文字につながっています。

ただし、中身のない変数をつなぐとエラーになります。中身のない変数には、「何も入っていない」を表すnil(ニル)が入っています。コマンドバーの中身を消してから、次の1行を入れてCtrl+Enterキーを押します。
local name print("スコア " .. name)
local name は、nameという変数を作るだけで、何も入れていません。この1行(画像の1)を動かすと、出力に赤い文字で「attempt to concatenate string with nil」(画像の2)と出ました。「文字とnilはつなげません」という意味です。

コードで変数を .. でつなぐときは、その変数に文字か数が入っているかを確かめます。
配列:順番に並べた入れ物
local padColors = {
Color3.fromRGB(255, 80, 80),
Color3.fromRGB(80, 200, 255),
}
table.insert(padColors, Color3.fromRGB(255, 220, 80))
| 書き方 | していること |
|---|---|
padColors[1] | 1番目を取り出す(Luaの配列は0ではなく1から数える) |
#padColors | 中に入っている数。このコードでは3 |
table.insert(配列, 値) | 後ろに1つ足す |
table.remove(配列, 番号) | その番号の1つを消す。後ろの番号が1つずつ前に詰まる |
コマンドバーでtable.removeを試す
消すと番号がどう変わるかを、コマンドバーで確かめます。まず、赤・青・黄の3つを入れた配列を作り、1番目・2番目・3番目と、入っている数(#)を出します。
local colors = {"赤", "青", "黄"} print(colors[1], colors[2], colors[3], #colors)
この1行(画像の1)を動かすと、出力に「赤 青 黄 3」(画像の2)と出ました。1番目が赤、2番目が青、3番目が黄で、全部で3つです。

次に、コマンドバーの中身を消して、table.remove(colors, 1) で1番目を消してから出す1行を入れます。
local colors = {"赤", "青", "黄"} table.remove(colors, 1) print(colors[1], colors[2], #colors)
この1行(画像の1)を動かすと、出力に「青 黄 2」(画像の2)と出ました。赤を消したので、それまで2番目だった青が1番目に、3番目だった黄が2番目に詰まり、数は2になっています。消すと、後ろの番号が1つずつ前に詰まります。

(score - 1) % #padColors + 1 は、1、2、3、1、2、3…と、配列の番号を順番にくり返すための計算です。% は割り算のあまりです。
辞書:名前(キー)で取り出す入れ物
local rankColors = {
Gold = Color3.fromRGB(255, 200, 40),
Silver = Color3.fromRGB(200, 200, 210),
}
辞書は番号ではなく名前で中身を取り出すテーブルです。rankColors["Gold"] または rankColors.Gold と書くと、金色が取り出せます。コードの rankColors[rank] は、rankに入っている名前(Goldなど)の色を取り出しています。
ipairs と pairs:中身を1つずつ取り出す
| 書き方 | 使う相手 | 取り出す順番 |
|---|---|---|
for i, v in ipairs(配列) do | 配列 | 1、2、3…と番号の順 |
for k, v in pairs(辞書) do | 辞書 | 決まっていない |
手順4の出力では、ipairsの「床の色」は1、2、3の順に出ました。pairsの「ランクの色」は、コードに書いたGold・Silver・Bronze・Noneの順ではなく、None・Bronze・Silver・Goldの順で出ました。辞書をpairsで取り出す順番は決まっていないので、順番が大事なときは配列を使います。
while:条件に合うあいだ、くり返す
while timeLeft > 0 do
task.wait(1)
timeLeft -= 1
showBoard()
end
whileは条件に合うあいだ、中に書いた行をくり返します。forは回数を決めてくり返し、whileは「0秒になるまで」のように終わる条件でくり返します。
whileで気をつけることは2つです。
| 気をつけること | 理由 |
|---|---|
中に task.wait を入れる | このコードで消すと、30回のくり返しが一瞬で終わり、すぐ「おわり!」になる。while true do のように終わらない条件で待つ行がないと、くり返しが休まずに回り続けてしまう |
| whileより下の行は、くり返しが終わるまで動かない | このコードでは、Touchedのつなぎをwhileより上に書いている。下に書くと、つながるのは30秒たったあとで、そのときはplayingがfalseなので、一度もスコアが増えない |
timeLeft -= 1 は timeLeft = timeLeft - 1 を短く書いたもので、score += 1 は1足す書き方です。
true と false:今の状態を覚えておく
playingは遊べる時間の途中ならtrue、終わったらfalseにしています。Touchedの中のifに playing を入れているので、playingがfalseになったあとは、踏んでもスコアが増えません。手順4で、おわりのあとに踏んでも12のままだったのはこのためです。
数字を変えて試す
| 変えたいこと | 変える場所 | 例 |
|---|---|---|
| 遊べる時間 | local timeLeft = 30 | 60にすると1分 |
| ランクに必要な点数 | getRankの >= 10 など | 20にするとGoldが出にくくなる |
| 床の色 | padColorsの中、table.insertの行 | 色を1つ足すと4色を順番に使う |
| ランクの名前と色 | rankColorsとgetRankの名前 | 「Platinum」を足すなら、両方に足す |
ランクの名前を足すときは、getRankで返す名前と、rankColorsのキーを同じにします。名前がちがうと、rankColors[rank] で色が見つからず(nil)、看板の色を変えられません。
うまく動かないときの直し方
| 症状 | 原因 | 直し方 |
|---|---|---|
| 看板に何も出ない | 名前のちがい、Faceの面 | ScoreBoard・SurfaceGui・TextLabelの名前をエクスプローラで確かめる。SurfaceGuiのFaceが「Back」か確かめる |
| 踏んでもスコアが増えない | Touchedの行がwhileより下にある | コードを全部貼り直す |
| 11点なのにBronzeになる | ifの条件の順番 | 大きい数の条件から先に書く |
| 看板の色が変わらない・赤い文字が出る | getRankの名前とrankColorsのキーがちがう | 大文字・小文字までそろえる |
出力の赤い文字の読み方は、スクリプトが動かないときの確認手順で解説しています。
AIに相談するときの伝え方
AIにコードを書いてもらったら、知らない書き方を1つずつ聞くと覚えやすくなります。
次のRobloxのLuauのコードの中で、elseif・return・..・table.insert・ipairs・pairs・whileを使っている行を1つずつ挙げて、何をしているかを中学生にも分かる言葉で説明してください。
(ここにコードを貼る)
よくある質問
LuaとLuauはちがう言語?
LuauはLua 5.1をもとにRobloxが作った言語です。if・for・while・テーブルなどの基本の書き方はLua 5.1と同じで、この記事の += のような便利な書き方が足されています。ただし、新しい版のLua(5.3や5.4)にだけある書き方や、パソコンのファイルを読み書きする機能などはRobloxでは使えません。Luaの本で覚えるときは、Lua 5.1の書き方を目安にします。
配列と辞書は、どちらを使えばいい?
順番に並べて使う物(色の順番、ステージの順番)は配列、名前で取り出したい物(ランクごとの色、アイテムごとの値段)は辞書が向いています。
次のステップ(中級 26/28)
次は、壁と屋根を組み、ドアと窓の穴を開けて家を建てます。
次に知りたいことを選ぶ
- 次のステップ:壁と屋根を組み、ドアと窓の穴を開けて家を建てます → ロブロックス(Roblox)スタジオで家を作る方法
- 変数・関数・for・イベントの読み方をおさらいしたい → スクリプトの読み方
- 看板に残り秒数を出す仕組みをもっと見たい → 消える床と時限の橋の作り方
- 赤い文字が出て動かない → スクリプトが動かないときの確認手順



