「ロブロックスで、引くとレアが出るガチャを作りたい」「激レアだけ出にくくするには、どうやって確率を決めるの?」
ロブロックス(Roblox)スタジオでガチャを作る方法を、実際の画像付きで誰でも簡単に分かるように解説します。ここでは、ピンクのガチャの機械に近づいてEキーを押すと、コインを10枚使って景品の玉が出るガチャを作ります。玉はノーマル(白)、レア(青)、激レア(黄色)の3種類で、出る確率は横の看板に表示します。
上級ステップ13/42 前の記事:ロブロックス(Roblox)のレースゲームの作り方 全体の順番を見る
使うもの:Roblox Studioが起動するパソコン、マウス、キーボード。コインの数を右上に出す仕組み(leaderstats)はコイン集めゲームの作り方、近づくと「E ○○する」と出る部品(ProximityPrompt)はNPCの作り方、看板に文字を出す方法は文字の入れ方で解説しています。
先に答え
| 知りたいこと | 答え |
|---|---|
| 確率の決め方 | 景品ごとに「重み」を決める(ノーマル70・レア25・激レア5)。重みが大きいほど出やすい |
| 抽選のしかた | 重みの合計(100)までの数を1つ引き、どの景品の範囲に入ったかで決める |
| 本当にその確率で出る? | 1万回引くと、ほぼ決めた確率どおりになった。10回だと大きくずれた(6節) |
| Robuxで引かせるとき | すべての景品と、その確率(合計100%)を、引く前に見せる決まりがある(8節) |
今回の完成状態:下の画像のように、機械の手前に黄色く光る玉が出て、看板に「前回:激レア」と出れば成功です。

1. ガチャの機械を置く
新しいBaseplateを開きます。エクスプローラの「Workspace」にマウスを乗せて、右に出る「+」を押し、一覧から「Part」を入れます。
入れたPartをエクスプローラで選んだままF2キーを押して、名前を「GachaMachine」に変えます。続けてGachaMachineのプロパティを次のように変えます。
| プロパティ | 値 |
|---|---|
| Size | 6, 8, 6 |
| Position(▼CFrameのすぐ下) | 0, 4, -16 |
| Color | 255, 80, 160 |
| Anchored | チェックを入れる |
どのプロパティも、GachaMachineを選んだ状態でプロパティの検索欄に名前(「Size」など)を入力し、右の欄を押して数字を書きかえてEnterキーを押します。Positionは「▼CFrame」のすぐ下のPositionに入れます。Anchoredは右の四角を押してチェックを入れます。
エクスプローラにGachaMachineが入り(画像の1)、スタートの台の先にピンクの機械が立ちます(画像の2)。

2. 近づくと「ガチャを引く」と出るようにする
エクスプローラの「GachaMachine」にマウスを乗せて、右に出る「+」を押します。一覧の検索欄に「ProximityPrompt」と入れ(画像の1)、一覧の「ProximityPrompt」を押します(画像の2)。

GachaMachineの中に「ProximityPrompt」が入ります。ProximityPromptを選んだ状態で、プロパティの検索欄に「Text」と入力します。ActionTextは最初「Interact」、ObjectTextは空になっています。ActionTextの右の欄を押して「ガチャを引く」に書きかえ、Enterキーを押します。続けてObjectTextの右の欄を押して「1回 10コイン」と入れ、Enterキーを押します(赤い枠)。

3. 確率の看板を置く
機械を複製して看板にする
エクスプローラで「GachaMachine」を選んだ状態でCtrl + Dキーを押すと、同じ場所に複製ができ、複製したほうが選ばれた状態になります(エクスプローラでは下に並んだGachaMachine)。そのままF2キーを押して名前を「OddsBoard」に変え、プロパティを次のように変えます。どれもGachaMachineと同じく、プロパティの検索欄に名前を入力し、右の欄を押して数字を書きかえてEnterキーを押します。Positionは「▼CFrame」のすぐ下のPositionに入れます。AnchoredはGachaMachineと同じままで大丈夫です。
| プロパティ | 値 |
|---|---|
| Size | 10, 6, 1 |
| Position(▼CFrameのすぐ下) | 11, 3, -16 |
| Color | 255, 255, 255 |
複製したOddsBoardの中にも、ProximityPromptが入っています。看板には要らないので、OddsBoardの左の「▶」を押して開き、中の「ProximityPrompt」を押して選んでから(赤い枠)、Deleteキーで消します。

看板に文字を出す部品を入れる
エクスプローラの「OddsBoard」にマウスを乗せて、右に出る「+」を押します。一覧の検索欄に「SurfaceGui」と入れ、「SurfaceGui」を押します。
SurfaceGuiは、パーツの1つの面に画面の部品を貼るものです。エクスプローラで入れたSurfaceGuiを選んだ状態で、プロパティの検索欄に「Face」と入力します。Faceは最初「Front」になっています。右の「Front」を押すと面の一覧が開くので、「Back」を押します(赤い枠)。Frontのままだと、スタートの台から見て看板の裏側に貼られてしまい、文字が見えません。

Faceが「Back」に変わります(赤い枠)。

続けて、エクスプローラの「SurfaceGui」にマウスを乗せて、右に出る「+」を押し、一覧から「TextLabel」を入れます。TextLabelを選んだままF2キーを押して、名前を「OddsText」に変えます。OddsTextのプロパティを次のように変えます。
| プロパティ | 値 | 理由 |
|---|---|---|
| Size | {1, 0},{1, 0} | 看板の面いっぱいに広げる(最初は {0, 200},{0, 50}) |
| TextScaled | チェックを入れる | 看板の大きさに合わせて文字を大きくする(最初はチェックなし) |
Sizeは、OddsTextを選んだ状態でプロパティの検索欄に「Size」と入力し、Sizeの右の欄を押して全部消してから「{1, 0},{1, 0}」と、かっこも入れてそのまま入力し、Enterキーを押します。TextScaledは、検索欄に「TextScaled」と入力し、右の四角を押してチェックを入れます。
エクスプローラにOddsTextが入り(画像の1)、TextScaledにチェックが入って(画像の2)、白い看板に「Label」の文字が大きく出れば準備は完了です(画像の3)。

看板に出す文字は、次のスクリプトが確率の表から書きます。手で書かないのは、確率を変えたときに看板の数字を直し忘れないようにするためです。
4. ガチャのスクリプトを書く
エクスプローラの「ServerScriptService」にマウスを乗せて、右に出る「+」を押し、一覧から「Script」を入れます。名前を「GachaScript」に変え、中のコードを全部消して、次のコードを貼り付けます。
local Players = game:GetService("Players")
local Debris = game:GetService("Debris")
local machine = workspace:WaitForChild("GachaMachine")
local prompt = machine:WaitForChild("ProximityPrompt")
local oddsText = workspace:WaitForChild("OddsBoard"):WaitForChild("SurfaceGui"):WaitForChild("OddsText")
local COST = 10 -- 1回に使うコイン
local START_COINS = 100 -- 試すために、最初に持たせるコイン
-- 景品の一覧。weight(重み)が大きいほど出やすい
local PRIZES = {
{ name = "ノーマル", weight = 70, color = Color3.fromRGB(230, 230, 230) },
{ name = "レア", weight = 25, color = Color3.fromRGB(0, 120, 255) },
{ name = "激レア", weight = 5, color = Color3.fromRGB(255, 200, 0) },
}
-- 重みをすべて足した数
local totalWeight = 0
for _, prize in PRIZES do
totalWeight += prize.weight
end
local random = Random.new()
-- 重みに合わせて、景品を1つ選ぶ
local function draw()
local number = random:NextInteger(1, totalWeight)
local sum = 0
for _, prize in PRIZES do
sum += prize.weight
if number <= sum then
return prize
end
end
end
-- 看板に、確率と前回の結果を出す
local function showBoard(message)
local lines = { "ガチャの確率" }
for _, prize in PRIZES do
local percent = prize.weight / totalWeight * 100
table.insert(lines, string.format("%s %.1f%%", prize.name, percent))
end
table.insert(lines, message or "")
oddsText.Text = table.concat(lines, "\n")
end
-- 参加した人に、コインを持たせる
Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local coins = Instance.new("IntValue")
coins.Name = "Coins"
coins.Value = START_COINS
coins.Parent = leaderstats
end)
local busy = {} -- 引いている途中の人
prompt.Triggered:Connect(function(player)
if busy[player] then return end
local coins = player.leaderstats.Coins
if coins.Value < COST then
showBoard("コインが足りません")
return
end
busy[player] = true
coins.Value -= COST
local prize = draw()
-- 景品の玉を、機械の手前に出す
local ball = Instance.new("Part")
ball.Name = prize.name
ball.Shape = Enum.PartType.Ball
ball.Size = Vector3.new(2, 2, 2)
ball.Color = prize.color
ball.Material = Enum.Material.Neon
ball.Position = machine.Position + Vector3.new(0, 0, 4)
ball.Parent = workspace
Debris:AddItem(ball, 10) -- 10秒たったら玉を消す
showBoard("前回:" .. prize.name)
print("結果:" .. prize.name)
task.wait(1)
busy[player] = nil
end)
Players.PlayerRemoving:Connect(function(player)
busy[player] = nil
end)
showBoard()
エクスプローラのServerScriptServiceの中にGachaScriptが入り(画像の1)、スクリプトの画面にコードが入ります(画像の2)。

重み付きの抽選のしくみ
ガチャの中心は、draw という関数です。重みの合計は70 + 25 + 5 = 100なので、random:NextInteger(1, totalWeight) は1から100までの数を1つ選びます。選んだ数がどの範囲に入ったかで、景品が決まります。
| 選ばれた数 | 景品 | 範囲の広さ | 確率 |
|---|---|---|---|
| 1〜70 | ノーマル | 70 | 70% |
| 71〜95 | レア | 25 | 25% |
| 96〜100 | 激レア | 5 | 5% |
for の中では、ノーマルの70、レアの25、激レアの5を順に sum に足していき、選んだ数が sum 以下になったところの景品を返します。たとえば83が出たときは、ノーマルまでの合計70より大きく、レアまでの合計95以下なので「レア」です。
重みは整数(1、5、70のような小数のない数)にします。重みは合計が100でなくても動きます。たとえば激レアを1にすると、合計が96になり、激レアの確率は1 ÷ 96で約1.0%になります。看板の数字も showBoard が重みから計算しているので、自動で変わります(7節)。
Random.new() は、Robloxが用意している乱数(決まった順番のない数)を作る道具です。NextInteger(1, 100) のように、最小と最大を入れると、その間の整数を1つ返します。
そのほかの行の役目
| 行 | 役目 |
|---|---|
if coins.Value < COST then | コインがCOSTで決めた10枚より少ないときは引かせず、看板に「コインが足りません」と出す |
busy[player] = true と task.wait(1) | Eキーを連打しても、1秒に1回しか引けないようにする |
Debris:AddItem(ball, 10) | 出た玉を10秒後に消し、玉がたまりすぎないようにする |
START_COINS = 100 | 試すために最初から100コインを持たせる。本物のゲームでは、コインを集めたり保存したりする仕組みとつなぐ |
5. テストする
3D画面の上の作品のタブ「Place1」を押して3D画面に戻り、F5キーでテストを始めます(タブの名前はパソコンによって違います)。
看板に「ガチャの確率」と、ノーマル70.0%・レア25.0%・激レア5.0%が出ます(画像の1)。
コインの数は右上の一覧に出ます。「Coins」が100です(画像の2)。一覧が出ないときは、3D画面を一度押してからTabキーを押すと出ます。もう一度Tabキーを押すと閉じます。

W・A・S・Dキーで歩いて機械に近づくと、「E」「1回 10コイン」「ガチャを引く」と出ます(赤い枠)。

Eキーを押すと、機械の手前に玉が出て(画像の1)、看板に「前回:」と出た玉の名前が出ます(画像の2)。下の画像は1回目でレア(青い玉)が出たところです。右上のCoinsは90に減ります(画像の3)。玉は固定していないので、出たあと床に落ちて転がります。

Shift + F5キーでテストを停止します。3D画面の上の作品のタブ「Place1」を押して3D画面に戻り、F5キーでテストを始め直すと、コインはSTART_COINSで決めた100に戻ります。アソビシフト編集部が試したときは、最初の1回のテスト(10回)では激レアが出ず、テストを始め直して引き続けたところで、黄色く光る玉(激レア)が出ました(画像の1)。看板には「前回:激レア」と出ます(画像の2)。

10回引いてCoinsが0になってからEキーを押すと、玉は出ず、看板に「コインが足りません」と出ます(画像の1)。右上のCoinsは0です(画像の2)。

Shift + F5キーでテストを停止します。
6. 引いた回数で確率はどうなる?
「激レア5%」は、20回引けば必ず1回出るという意味ではありません。本当に決めた確率どおりに出るのか、同じ抽選の式をコマンドバーで何回も動かして確かめます。
コマンドバーは、画面の下の出力の欄のさらに下にある、1行の入力欄です(赤い枠)。テストを停止した状態で使います。

コマンドバーに次の1行を貼り付けて、Ctrl + Enterキー(または右はしの「走る」)を押します。GachaScriptと同じ70・25・5の重みで、10回だけ引いた結果を出力に出します。
local W = { 70, 25, 5 } local N = { "ノーマル", "レア", "激レア" } local c = { 0, 0, 0 } local r = Random.new() for i = 1, 10 do local n = r:NextInteger(1, 100) local s = 0 for k = 1, 3 do s += W[k] if n <= s then c[k] += 1 break end end end for k = 1, 3 do print(N[k], c[k] .. "回") end
出力の欄に、入れた1行(画像の1)と、10回の結果(画像の2)が出ます。

以下は、アソビシフト編集部が10回の抽選を3回ためした結果です。
| ノーマル | レア | 激レア | |
|---|---|---|---|
| 1回目 | 8回 | 2回 | 0回 |
| 2回目 | 5回 | 5回 | 0回 |
| 3回目 | 6回 | 4回 | 0回 |
10回ずつでは、3回とも激レアは1回も出ませんでした。2回目はノーマルとレアが同じ5回ずつで、決めた70%と25%から大きくずれています。
上記の1行の中の { 70, 25, 5 } と NextInteger(1, 100) の100は、GachaScriptの重みと合計を写したものです。GachaScriptの重みを変えたときは、この2か所も同じように変えます。
次に、回数を1万回にします。コマンドバーに次の1行を貼り付けて、Ctrl + Enterキー(または右はしの「走る」)を押します。
local W = { 70, 25, 5 } local N = { "ノーマル", "レア", "激レア" } local c = { 0, 0, 0 } local r = Random.new() for i = 1, 10000 do local n = r:NextInteger(1, 100) local s = 0 for k = 1, 3 do s += W[k] if n <= s then c[k] += 1 break end end end for k = 1, 3 do print(N[k], c[k] .. "回", c[k] / 100 .. "%") end
出力の欄に、それぞれの回数と割合が出ます(赤い枠)。数字は乱数で決まるので、引くたびに変わります。下の画像と同じ数にならなくても、ノーマル・レア・激レアがそれぞれ70%・25%・5%に近ければ正しく動いています。

以下は、1万回の抽選を3回ためした結果です。
| ノーマル(決めた確率70%) | レア(25%) | 激レア(5%) | |
|---|---|---|---|
| 1回目 | 7032回(70.32%) | 2507回(25.07%) | 461回(4.61%) |
| 2回目 | 6969回(69.69%) | 2522回(25.22%) | 509回(5.09%) |
| 3回目 | 6992回(69.92%) | 2467回(24.67%) | 541回(5.41%) |
1万回では、3回ともノーマルは70%、レアは25%、激レアは5%に近い数になりました。それでも激レアは4.61%から5.41%まで、毎回少しずつ違います。
引く回数が少ないうちは、運でかたよります。テストで何回か引いただけで「激レアが出すぎる」「出なさすぎる」と決めず、このように回数を多くして確かめると安心です。
7. 確率を変える
激レアをもっと出にくくしてみます。3D画面の上のタブ「GachaScript」を押して、スクリプトの画面に戻ります。15行目の激レアの行の weight = 5 を weight = 1 に書きかえます。
書きかえたあとの景品の一覧は、次のようになります(変えたのは激レアの行の数字だけです)。
local PRIZES = {
{ name = "ノーマル", weight = 70, color = Color3.fromRGB(230, 230, 230) },
{ name = "レア", weight = 25, color = Color3.fromRGB(0, 120, 255) },
{ name = "激レア", weight = 1, color = Color3.fromRGB(255, 200, 0) },
}
3D画面の上の作品のタブ「Place1」を押して3D画面に戻り、F5キーでテストを始めます(タブの名前はパソコンによって違います)。看板の数字が、ノーマル72.9%・レア26.0%・激レア1.0%に変わります(赤い枠)。重みの合計が96になったので、看板の確率も自動で計算し直されています。
3つを足すと99.9%で、ちょうど100%になりません。看板では小数第1位までに丸めているためです。無料のコインで引くこの記事のガチャでは問題ありませんが、Robuxで引かせるときは8節の決まりに合わせます。公式の決まりでは、確率の合計はちょうど100%にします。小数が長く続くときだけ、最初の0でない桁から4桁以上下まで残して丸め(1 ÷ 96なら1.0417%)、「確率は丸めているため、合計が100%にならないことがあります」と書き添えます。その場合は、showBoard の中の %.1f を %.4f に変えると、小数第4位まで出ます。

Shift + F5キーでテストを停止します。タブ「GachaScript」を押してスクリプトの画面に戻り、weight = 1 を weight = 5 に戻します。
8. Robuxで引かせるときのルール
ここまで作ったガチャは、ゲームの中で無料でもらったコインで引くものです。Robux(Robloxのお金)で引かせたり、Robuxで買えるコインやチケットで引かせたりする場合は、Robloxの決まりに従う必要があります。
確率を必ず見せる
Robloxの公式の説明では、Robuxで直接または間接的に買えるランダムな景品を「有料のランダムアイテム」と呼び、次の決まりがあります。
| 決まり | 内容 |
|---|---|
| 何が対象か | Robuxでガチャを回す、Robuxで買ったチケットやカギで回す、たまごをかえしてペットをもらう、宝箱を開ける、効く時間がランダムな薬、2つを合わせて良い物を狙う合成、確率を上げるアイテム、天井(何回か引くと必ず出る仕組み) など |
| 見せるもの | 出る可能性のある景品をすべてと、それぞれの実際の確率 |
| 確率の書き方 | パーセントで書き、すべての確率を足すとちょうど100%になること。小数が長く続くときだけ、最初の0でない桁から4桁以上下まで残して丸め、丸めていることを書き添えてよい |
| 同じ確率の景品が多いとき | 一覧の初めに「以下はどれも〇%」とまとめて書いてよい |
| 1回しか手に入らない景品があるとき | 手に入れたあとは、その人の残りの確率に直して見せる |
| 景品が多くて3D画面に収まらないとき | 「詳細」などの言葉の付いたボタンで、引く前に一覧を開けるようにしてもよい。言葉のない「(i)」の印だけではだめ |
| 確率を上げるアイテム | 買う前に、どれだけ上がるかを数字で説明し、使っている間は上がった確率を見せる |
| 無料のとき | Robuxやそれで買えるお金を使わずに手に入るランダムな景品は、確率を見せなくてもよい |
この記事のガチャは無料のコインで引くので、確率を見せなくても決まりには反しません。それでも看板に確率を出しておくと、遊ぶ人が安心して引けます。
有料のガチャを使えない人がいる
国や地域の決まりなどによって、有料のランダムアイテムを使えない人がいます。Robloxの公式の説明では、PolicyService の GetPolicyInfoForPlayerAsync で、その人が使えるかどうかを調べます。返ってくる表の ArePaidRandomItemsRestricted が true の人には、有料のガチャを引かせてはいけません。
local PolicyService = game:GetService("PolicyService")
-- その人が有料のガチャを使えないなら true を返す
local function isRestricted(player)
local ok, info = pcall(function()
return PolicyService:GetPolicyInfoForPlayerAsync(player)
end)
if not ok then
return true -- 調べられなかったときは、使えない人として扱う
end
return info.ArePaidRandomItemsRestricted
end
これは、Robuxで引かせるガチャに作りかえるときに足す部分です。この記事の無料のガチャには入れなくて大丈夫です。使うときは、GachaScriptの上のほう(local の行が並ぶところの下)にこの関数を置き、引く処理の最初で isRestricted(player) が true なら引かせずに終わるようにします。
アソビシフト編集部が日本のアカウントでStudioのテストを始め、コマンドバーで調べたところ、ArePaidRandomItemsRestrictedは false(有料のガチャを使える)でした。公式の説明では、この結果は住んでいる国や地域だけでなく、年れいや遊んでいる機種によっても変わります。そのため、Robuxで引かせるガチャを作るときは、このように1人ずつ調べてから引かせます。
使えない人には、次のどれかの方法で対応する決まりです。また、同じ表の IsPaidItemTradingAllowed が false の人には、有料のランダムアイテムなどで手に入れた物を、ほかの人と交換させてはいけません(編集部のテストでは true でした)。
| 対応 | 例 |
|---|---|
| お金を払わずに手に入る道を用意する | ゲームを進めるとたまごが無料でもらえる |
| 出る順番を決めて、引く前に見せる | 1回目は必ず5コイン、2回目は必ず10コイン |
| 景品をそのまま買えるようにする | 出る見込みに合わせた値段で直接売る(10 Robuxのガチャで5%の剣なら200 Robux) |
| 有料のガチャを見せない | ガチャの機械の代わりに、直接買える店を置く |
| 買おうとしたら説明を出す | 「お住まいの地域では利用できません」と出す |
| ガチャのある場所に入れない | その人を別の場所へ移動させる |
Robuxで売る仕組みは開発者製品の作り方で解説しています。
うまくいかないとき
| こまっていること | 見るところ | 直し方 |
|---|---|---|
| 近づいても「E ガチャを引く」が出ない | ProximityPromptの場所 | GachaMachineの中に入っているか確かめる |
| Eキーを押しても何も起きない | 出力の赤い文字 | 名前が「GachaMachine」「OddsBoard」「OddsText」とコードで同じか確かめる |
| 看板に文字が出ない | SurfaceGuiのFace | スタートの台から見える面(Back)になっているか確かめる |
| 看板の文字が小さい | OddsTextのTextScaled | チェックを入れる |
| 玉が出ても転がっていく | 玉は固定していない | 転がしたくないときは、コードの ball.Parent = workspace の行の前に ball.Anchored = true の1行を足す |
| 右上にコインの数が出ない | 一覧が閉じている | 3D画面を一度押してからTabキーを押す |
| 激レアが全然出ない | 引いた回数 | 5%は20回に1回出るという意味ではない。6節のように回数を多くして確かめる |
よくある質問
引いた景品を保存できる?
この記事では、出た景品は玉として10秒出るだけで、保存していません。持ち物として残すには、景品の名前をプレイヤーごとに記録し、DataStoreの使い方の方法で保存します。
確率を見せずに無料のガチャを作ってもいい?
公式の説明では、Robuxやそれで買えるお金を使わずに引けるガチャは、確率を見せる決まりの対象外です。ただし、あとでRobuxで買えるコインでも引けるようにしたときは対象になるので、最初から確率を表示しておくと直す手間がかかりません。
次は、拾った物をマス目の一覧に並べて、抜けても残る持ち物を作ります。次のステップ(上級 14/42)
次に知りたいことを選ぶ
- 次のステップ:拾った物をマス目の一覧に並べて、抜けても残る持ち物を作ります → ロブロックス(Roblox)スタジオでインベントリ(持ち物)を作る方法
- ガチャで使うコインを集めさせたい → ロブロックス(Roblox)のコイン集めゲームの作り方
- コインで買える店も作りたい → ロブロックス(Roblox)のショップの作り方