「ロブロックスで、友だちが叫ぶような怖いゲームを作りたい」「暗い場所を懐中電灯で進むゲームはどうやって作るの?」
ロブロックス(Roblox)のホラーゲームの作り方を、実際の画像付きで誰でも簡単に分かるように解説します。ここでは、真っ暗な館の中を懐中電灯で照らしながら進み、カギを拾って出口から脱出するゲームを作ります。館の奥には怪物がいて、近づくと追いかけてきます。つかまると赤い画面と叫び声でスタートへ戻されます。
上級ステップ11/42 前の記事:ロブロックス(Roblox)スタジオでモデルを作る方法 全体の順番を見る
使うもの:Roblox Studioが起動するパソコン、マウス、キーボード。この記事は、これまでの記事で作った仕組みを組み合わせて1本のゲームにする卒業制作です。追ってくる敵は追いかけてくる敵の作り方、手に持つ道具は手に持てるアイテムの作り方、夜の明るさは夜にする方法、サーバーからプレイヤーの画面へ合図を送る仕組みはRemoteEventの使い方で解説しています。
今回の完成状態:下の画像のように、真っ暗な館の中で「???」という名前の黒い怪物が近づいてくれば成功です。カギを持たずに出口のドアへ触れると「カギがかかっている…」と出ます。

ゲームの流れと部品
作るゲームは、館の中の4つの場所を順に回ります。上から見た館が下の画像です。

| 番号 | 場所 | すること |
|---|---|---|
| 1 | スポーン地点(南の部屋) | ここから始まる。つかまるとここへ戻る |
| 2 | カギ(まん中の部屋の西) | 触れるとカギを手に入れる |
| 3 | 怪物(北の部屋) | 25スタッドより近づいた人を追いかける(壁の向こうでも、近ければ気づく) |
| 4 | 出口のドア | カギを持っていれば開く。外の緑の床がゴール |
使う部品は次のとおりです。
| 部品 | 種類 | 置く場所 | 役目 |
|---|---|---|---|
| Mansion | フォルダー | Workspace | 館の壁7枚をまとめる |
| ExitDoor・Goal・Key | パーツ | Workspace | 出口のドア、ゴール、カギ |
| Monster | キャラクター | Workspace | 追ってくる怪物 |
| HorrorEvent | RemoteEvent | ReplicatedStorage | サーバーからプレイヤーの画面へ合図を送る |
| HorrorService | Script | ServerScriptService | 怪物・カギ・ドア・ゴールを動かす |
| HorrorClient | LocalScript | StarterPlayerScripts | 文字と赤い画面を出し、叫び声を鳴らす |
| Flashlight | Tool | StarterPack | 手に持つ懐中電灯 |
| Scream | Sound | SoundService | つかまったときの叫び声 |
1. 館の壁を作る
Studioを起動し、左の「テンプレート」から「Baseplate」(赤い枠)を押して、新しい作品を開きます。

エクスプローラの「Workspace」にマウスを乗せて、右に出る「+」を押します。開いた一覧の検索欄に「Folder」と入れて、一覧の「Folder」を押します。フォルダーが選ばれた状態でF2キーを押し、「Mansion」と入れてEnterキーを押します。
次に「Mansion」にマウスを乗せて「+」を押します。一覧の検索欄に「Part」と入れて、一覧の「Part」を押します。入ったPartが選ばれた状態でF2キーを押し、「WallSouth」と入れてEnterキーを押します。これが館の南の壁(スポーン地点の後ろ)です。エクスプローラでは、Mansionの中にWallSouth(画像の1)が入っています。
WallSouthを選んだ状態で、プロパティの検索欄に「Size」と入れます。Sizeの欄を押して「60, 12, 1」と入れ、Enterキーを押します(画像の2)。

続けてWallSouthを選んだまま、残りのプロパティを変えます。入れる値は次のとおりです。
| プロパティ | 値 | 意味 |
|---|---|---|
| Position(▼CFrame のすぐ下) | 0, 6, 6 | スポーン地点のすぐ後ろ |
| Material | Brick | れんがの見た目 |
| Color | 99, 95, 98(Dark stone grey) | 暗い灰色 |
| Anchored | チェックを入れる | 固定して倒れないようにする |
- プロパティの検索欄に「Position」と入れます。Positionは3つ出るので、▼CFrame のすぐ下のPositionの欄を押して「0, 6, 6」と入れ、Enterキーを押します(下の1枚目)。
- 検索欄に「Material」と入れます。Materialの欄を押して、出た一覧から「Brick」を選びます(2枚目)。
- 検索欄に「Color」と入れます。Colorの欄の右の数字の部分を押して「99, 95, 98」と入れ、Enterキーを押します。欄に「[99, 95, 98] (Dark stone grey)」と出ます(3枚目)。左の色の四角を押すと色を選ぶ窓が開くので、数字の部分を押します。
- 検索欄に「Anchored」と入れ、Anchoredの右の四角を押してチェックを入れます(4枚目)。
残りの6枚は、WallSouthを複製して作ります。Material・Color・Anchoredは、複製するとWallSouthと同じ値になるので変えません。1枚ずつ、次の1〜5の順に作ります。
1枚目:WallWest(西の外側の壁)
- エクスプローラでWallSouthを押して選びます。WallSouthを選んだ状態でCtrl + Dキーを押します。
- Mansionの中に同じ見た目の壁がもう1枚でき、複製したほうが選ばれた状態になります。
- そのままF2キーを押し、「WallWest」と入れてEnterキーを押します。
- WallWestを選んだまま、プロパティの検索欄に「Size」と入れ、Sizeの欄に「1, 12, 62」と入れてEnterキーを押します。
- 検索欄に「Position」と入れ、▼CFrame のすぐ下のPositionの欄に「-30, 6, -25」と入れてEnterキーを押します。
2枚目:WallEast(東の外側の壁)
- エクスプローラでWallSouthを押して選びます。WallSouthを選んだ状態でCtrl + Dキーを押します。
- Mansionの中に同じ見た目の壁がもう1枚でき、複製したほうが選ばれた状態になります。
- そのままF2キーを押し、「WallEast」と入れてEnterキーを押します。
- WallEastを選んだまま、プロパティの検索欄に「Size」と入れ、Sizeの欄に「1, 12, 62」と入れてEnterキーを押します。
- 検索欄に「Position」と入れ、▼CFrame のすぐ下のPositionの欄に「30, 6, -25」と入れてEnterキーを押します。
3枚目:InnerWall1(南とまん中の部屋の仕切り。東にすき間)
- エクスプローラでWallSouthを押して選びます。WallSouthを選んだ状態でCtrl + Dキーを押します。
- Mansionの中に同じ見た目の壁がもう1枚でき、複製したほうが選ばれた状態になります。
- そのままF2キーを押し、「InnerWall1」と入れてEnterキーを押します。
- InnerWall1を選んだまま、プロパティの検索欄に「Size」と入れ、Sizeの欄に「46, 12, 1」と入れてEnterキーを押します。
- 検索欄に「Position」と入れ、▼CFrame のすぐ下のPositionの欄に「-7, 6, -18」と入れてEnterキーを押します。
4枚目:InnerWall2(まん中と北の部屋の仕切り。西にすき間)
- エクスプローラでWallSouthを押して選びます。WallSouthを選んだ状態でCtrl + Dキーを押します。
- Mansionの中に同じ見た目の壁がもう1枚でき、複製したほうが選ばれた状態になります。
- そのままF2キーを押し、「InnerWall2」と入れてEnterキーを押します。
- InnerWall2を選んだまま、プロパティの検索欄に「Size」と入れ、Sizeの欄に「46, 12, 1」と入れてEnterキーを押します。
- 検索欄に「Position」と入れ、▼CFrame のすぐ下のPositionの欄に「7, 6, -38」と入れてEnterキーを押します。
5枚目:WallNorthLeft(北の壁の左)
- エクスプローラでWallSouthを押して選びます。WallSouthを選んだ状態でCtrl + Dキーを押します。
- Mansionの中に同じ見た目の壁がもう1枚でき、複製したほうが選ばれた状態になります。
- そのままF2キーを押し、「WallNorthLeft」と入れてEnterキーを押します。
- WallNorthLeftを選んだまま、プロパティの検索欄に「Size」と入れ、Sizeの欄に「26, 12, 1」と入れてEnterキーを押します。
- 検索欄に「Position」と入れ、▼CFrame のすぐ下のPositionの欄に「-17, 6, -56」と入れてEnterキーを押します。
6枚目:WallNorthRight(北の壁の右)
- エクスプローラでWallSouthを押して選びます。WallSouthを選んだ状態でCtrl + Dキーを押します。
- Mansionの中に同じ見た目の壁がもう1枚でき、複製したほうが選ばれた状態になります。
- そのままF2キーを押し、「WallNorthRight」と入れてEnterキーを押します。
- WallNorthRightを選んだまま、プロパティの検索欄に「Size」と入れ、Sizeの欄に「26, 12, 1」と入れてEnterキーを押します。
- 検索欄に「Position」と入れ、▼CFrame のすぐ下のPositionの欄に「17, 6, -56」と入れてEnterキーを押します。
6枚とも作ったら、入れた値を次の表で見直します。
| 名前 | Size | Position(▼CFrame のすぐ下) | 場所 |
|---|---|---|---|
| WallWest | 1, 12, 62 | -30, 6, -25 | 西の外側の壁 |
| WallEast | 1, 12, 62 | 30, 6, -25 | 東の外側の壁 |
| InnerWall1 | 46, 12, 1 | -7, 6, -18 | 南とまん中の部屋の仕切り(東にすき間) |
| InnerWall2 | 46, 12, 1 | 7, 6, -38 | まん中と北の部屋の仕切り(西にすき間) |
| WallNorthLeft | 26, 12, 1 | -17, 6, -56 | 北の壁の左 |
| WallNorthRight | 26, 12, 1 | 17, 6, -56 | 北の壁の右 |
3D画面を上から見るには、3D画面の上で右クリックを押したままマウスを動かしてカメラを回し、マウスのホイールを回して遠ざけます。7枚がそろうと、上から見て「S」の字のように折れ曲がった通路になります(画像の2)。エクスプローラのMansionの中に、7枚の壁が並んでいます(画像の1)。仕切りの壁のすき間を左右交互に開けているので、まっすぐ出口へは走れません。館の中を回って進むことになります。

2. 出口のドア・ゴール・カギを置く
出口のドア
エクスプローラの「Workspace」にマウスを乗せて「+」を押します。一覧の検索欄に「Part」と入れて、一覧の「Part」を押します。入ったPartが選ばれた状態でF2キーを押し、「ExitDoor」と入れてEnterキーを押します(画像の1)。入れたPartは、3D画面のまん中に見えている場所に置かれるので、カメラの向きによって出る場所が変わります。場所はこのあとPositionで決めるので、どこに出ても大丈夫です。
ExitDoorを選んだ状態で、プロパティの検索欄に「Size」と入れます。Sizeの欄に「8, 12, 1」と入れてEnterキーを押します(画像の2)。北の2枚の壁の間のすき間をふさぐ大きさです。

続けて検索欄に「Position」と入れ、▼CFrame のすぐ下のPositionの欄に「0, 6, -56」と入れてEnterキーを押します(画像の1)。北の壁のすき間に、ドア(画像の2)がはまりました。

ExitDoorを選んだまま、残りの3つを変えて木のドアにします。
| プロパティ | 値 |
|---|---|
| Anchored | チェックを入れる |
| Material | WoodPlanks |
| Color | 105, 64, 40 |
- 検索欄に「Anchored」と入れ、Anchoredの右の四角を押してチェックを入れます。
- 検索欄に「Material」と入れ、Materialの欄を押して一覧から「WoodPlanks」を選びます。
- 検索欄に「Color」と入れ、Colorの欄の右の数字の部分を押して「105, 64, 40」と入れ、Enterキーを押します。
下の3枚は、1〜3をそれぞれ終えたところです(画像の1が選んでいるExitDoor、画像の2が変えた欄)。3枚目では、ドアが茶色の木の板になっています。編集部は部品を先にまとめて置いてから撮ったので、エクスプローラにはこのあとの節で作るGoalとKeyも写っています。手順どおりに進めた画面では、まだGoalとKeyはありません。
ゴール
エクスプローラの「Workspace」にマウスを乗せて「+」を押し、一覧の検索欄に「Part」と入れて「Part」を押します。入ったPartが選ばれた状態でF2キーを押し、「Goal」と入れてEnterキーを押します(画像の1)。入れたPartは、3D画面のまん中に見えている場所に置かれるので、カメラの向きによって出る場所が変わります。場所はこのあとPositionで決めるので、どこに出ても大丈夫です。
Goalを選んだ状態で、プロパティの検索欄に「Size」と入れ、Sizeの欄に「8, 1, 8」と入れてEnterキーを押します(画像の2)。

続けて検索欄に「Position」と入れ、▼CFrame のすぐ下のPositionの欄に「0, 0.5, -63」と入れてEnterキーを押します(赤い枠)。ドアの外側の地面の上です。

Goalを選んだまま、残りの3つを変えて、暗い中でも光る緑の床にします。
| プロパティ | 値 |
|---|---|
| Anchored | チェックを入れる |
| Material | Neon |
| Color | 0, 255, 0 |
- 検索欄に「Anchored」と入れ、Anchoredの右の四角を押してチェックを入れます。
- 検索欄に「Material」と入れ、Materialの欄を押して一覧から「Neon」を選びます。
- 検索欄に「Color」と入れ、Colorの欄の右の数字の部分を押して「0, 255, 0」と入れ、Enterキーを押します。
下の3枚は、1〜3をそれぞれ終えたところです(画像の1が選んでいるGoal、画像の2が変えた欄)。Goalは館の外の北にあるので、この向きの3D画面には写っていません。
カギ
エクスプローラの「Workspace」にマウスを乗せて「+」を押し、一覧の検索欄に「Part」と入れて「Part」を押します。入ったPartが選ばれた状態でF2キーを押し、「Key」と入れてEnterキーを押します(画像の1)。入れたPartは、3D画面のまん中に見えている場所に置かれるので、カメラの向きによって出る場所が変わります。場所はこのあとPositionで決めるので、どこに出ても大丈夫です。
Keyを選んだ状態で、プロパティの検索欄に「Size」と入れ、Sizeの欄に「1, 1, 2」と入れてEnterキーを押します(画像の2)。

続けて検索欄に「Position」と入れ、▼CFrame のすぐ下のPositionの欄に「-24, 2, -28」と入れてEnterキーを押します(画像の1)。まん中の部屋の西の端に、小さなカギ(画像の2)が浮きました。

宙に浮いたまま止めておくため、検索欄に「Anchored」と入れ、Anchoredの右の四角を押してチェックを入れます。(画像の1が選んでいるKey、画像の2がAnchored)

カギは暗い館の中でも見つけられるように光らせます。検索欄に「Material」と入れ、Materialの欄を押して一覧から「Neon」を選びます(赤い枠)。

続けて検索欄に「Color」と入れ、Colorの欄の右の数字の部分を押して「255, 200, 0」と入れ、Enterキーを押します。カギが黄色になります(画像の1が選んでいるKey、画像の2が変えたColorの欄)。

最後に、検索欄に「CanCollide」と入れ、CanCollideの右の四角を押してチェックを外します(赤い枠)。チェックが入っているとカギに体がぶつかって押し戻されます。外しても、触れたことはスクリプトで分かります。

3. 怪物を置く
上の「ホーム」タブの「キャラクター」(画像の1)を押します。「リグを生成」の窓が開くので、「ブロック型アバター(2012年)」(画像の2)を押します。上のリグタイプ(R15)と体型(男子型)は、最初に選ばれているままで大丈夫です。

3D画面のまん中にアバター(画像の1)が入り、エクスプローラに「Rig」(画像の2)ができます。

エクスプローラでRigを選んだ状態でF2キーを押し、「Monster」と入れてEnterキーを押します(赤い枠)。スクリプトはこの名前で怪物を探すので大文字のMで始めます。

Monsterを選んだまま、プロパティの検索欄に「Origin」と入れます。▼Origin のすぐ下のPositionの欄に「18, 3, -48」と入れて、Enterキーを押します(画像の1)。怪物(画像の2)が北の部屋の右奥に動きました。

怪物を黒くして、名前を「???」にする
エクスプローラのMonsterの左の「▶」を押して開き、中の「Body Colors」(画像の1)を押します。Body Colorsは、アバターの頭・腕・足・胴の色をまとめて決める部品です。
Body Colorsを選んだ状態で、プロパティの検索欄に「Color3」と入れます。「HeadColor3」「LeftArmColor3」「LeftLegColor3」「RightArmColor3」「RightLegColor3」「TorsoColor3」の6つだけが出ます。上の「HeadColor3」の欄の右の数字の部分を押して「20, 20, 20」と入れ、Enterキーを押します。残りの5つも、同じように1つずつ「20, 20, 20」にします(画像の2)。怪物が真っ黒になりました。

続けてエクスプローラで、Monsterの中の「Humanoid」(画像の1)を押します。Humanoidは、キャラクターの体力や歩く速さ、頭の上の名前を受け持つ部品です。
Humanoidを選んだ状態で、プロパティの検索欄に「DisplayName」と入れます。DisplayNameの欄に「???」と入れて、Enterキーを押します(画像の2)。怪物の頭の上の名前が「???」に変わりました(画像の3)。正体の分からない怖さが出ます。

怪物は歩かせるので、固定されていないことを確かめます。エクスプローラで、Monsterの中のいちばん下のほうにある「HumanoidRootPart」(画像の1)を押します。HumanoidRootPartは、キャラクターの体の中心になる見えない部品です。プロパティの検索欄に「Anchored」と入れ、チェックが入っていないことを確かめます(画像の2)。キャラクターのボタンで入れたアバターは、最初からチェックが入っていません。

4. 合図を送るRemoteEventを入れる
RemoteEventは、サーバー(ゲームの正しい状態を持っている側)とプレイヤーのパソコンの間で合図を送るための部品です。
エクスプローラの「ReplicatedStorage」にマウスを乗せて「+」を押します。一覧の検索欄に「RemoteEvent」と入れて、一覧の「RemoteEvent」を押します。入ったRemoteEventが選ばれた状態でF2キーを押し、「HorrorEvent」と入れてEnterキーを押します(赤い枠)。

怪物につかまったか、カギを拾ったかを決めるのはサーバー(HorrorService)です。決まったことを、そのプレイヤーの画面(HorrorClient)へ知らせるのがHorrorEventです。
5. 怪物・カギ・ドアを動かすスクリプトを入れる
エクスプローラの「ServerScriptService」にマウスを乗せて「+」を押します。一覧の検索欄に「Script」と入れて、一覧の「Script」を押します。入ったScriptが選ばれた状態でF2キーを押し、「HorrorService」と入れてEnterキーを押します(下の画像の上の赤い枠)。
HorrorServiceを選んだ状態で、プロパティの検索欄に「RunContext」と入れます。RunContextは、スクリプトをサーバーとプレイヤーのパソコンのどちらで動かすかを決める設定です。▼動作 の下のRunContextの欄を押して、一覧から「Server」を選びます(下の赤い枠)。

エクスプローラのHorrorServiceをダブルクリックして開きます。中身を全部消して、次のコードを貼り付けます(コードの画面の中を押してからCtrl + Aキーで全部選び、Deleteキーで消します)。
local Players = game:GetService("Players")
local PathfindingService = game:GetService("PathfindingService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local horrorEvent = ReplicatedStorage:WaitForChild("HorrorEvent")
local monster = workspace:WaitForChild("Monster")
local humanoid = monster:WaitForChild("Humanoid")
local root = monster:WaitForChild("HumanoidRootPart")
local key = workspace:WaitForChild("Key")
local exitDoor = workspace:WaitForChild("ExitDoor")
local goal = workspace:WaitForChild("Goal")
local CHASE_RANGE = 25 -- この距離(スタッド)より近い人を追いかける
local STEPS_BEFORE_RECALC = 4 -- 道の点をいくつ進んだら計算し直すか
local START_POSITION = root.Position -- 怪物が最初にいた場所
humanoid.WalkSpeed = 13 -- プレイヤー(16)より少し遅くして、逃げられるようにする
local ok = pcall(function()
root:SetNetworkOwner(nil)
end)
if not ok then
warn("Monster のパーツの Anchored を外してください")
end
local path = PathfindingService:CreatePath({
AgentRadius = 2,
AgentHeight = 5,
AgentCanJump = false,
})
-- いちばん近い、生きているプレイヤーの HumanoidRootPart を探す
local function findNearestTarget()
local nearest = nil
local nearestDistance = CHASE_RANGE
for _, player in Players:GetPlayers() do
local character = player.Character
local targetHumanoid = character and character:FindFirstChildOfClass("Humanoid")
local targetRoot = character and character:FindFirstChild("HumanoidRootPart")
local escaped = player:GetAttribute("Escaped") -- 脱出した人は追わない
if targetHumanoid and targetRoot and targetHumanoid.Health > 0 and not escaped then
local distance = (targetRoot.Position - root.Position).Magnitude
if distance < nearestDistance then
nearest = targetRoot
nearestDistance = distance
end
end
end
return nearest
end
-- 怪物に触れた人を倒して、その人の画面に「つかまった」を出す
local function onMonsterTouched(hit)
local character = hit.Parent
local player = Players:GetPlayerFromCharacter(character)
if not player or player:GetAttribute("Escaped") then return end -- アバター以外や、脱出した人は何もしない
local targetHumanoid = character:FindFirstChildOfClass("Humanoid")
if not targetHumanoid or targetHumanoid.Health <= 0 then return end
targetHumanoid.Health = 0
horrorEvent:FireClient(player, "caught")
end
for _, part in monster:GetDescendants() do
if part:IsA("BasePart") then
part.Touched:Connect(onMonsterTouched)
end
end
-- カギに触れた人は、カギを持っていることにする
key.Touched:Connect(function(hit)
local player = Players:GetPlayerFromCharacter(hit.Parent)
if not player or player:GetAttribute("HasKey") then return end
player:SetAttribute("HasKey", true)
key.Transparency = 1
key.CanTouch = false
horrorEvent:FireClient(player, "message", "カギを手に入れた!出口のドアへ行こう")
end)
-- カギを持っている人が触れると、出口のドアが開く
local lastDoorMessage = {}
exitDoor.Touched:Connect(function(hit)
local player = Players:GetPlayerFromCharacter(hit.Parent)
if not player then return end
if player:GetAttribute("HasKey") then
exitDoor.Transparency = 0.8
exitDoor.CanCollide = false
else
-- 押しつけたままでも、文字を送るのは3秒に1回まで
local now = os.clock()
if lastDoorMessage[player] and now - lastDoorMessage[player] < 3 then return end
lastDoorMessage[player] = now
horrorEvent:FireClient(player, "message", "カギがかかっている…")
end
end)
Players.PlayerRemoving:Connect(function(player)
lastDoorMessage[player] = nil
end)
-- ゴールに着いた人に「脱出成功」を出す
goal.Touched:Connect(function(hit)
local player = Players:GetPlayerFromCharacter(hit.Parent)
if not player or player:GetAttribute("Escaped") then return end
player:SetAttribute("Escaped", true)
horrorEvent:FireClient(player, "escaped")
end)
-- 行き先までの道を計算して、少しだけ進む
local function walkWithPath(destination)
local success = pcall(function()
path:ComputeAsync(root.Position, destination)
end)
if success and path.Status == Enum.PathStatus.Success then
local waypoints = path:GetWaypoints()
local last = math.min(#waypoints, 1 + STEPS_BEFORE_RECALC)
for i = 2, last do
humanoid:MoveTo(waypoints[i].Position)
local reached = humanoid.MoveToFinished:Wait()
if not reached then
break
end
end
else
humanoid:MoveTo(destination)
end
task.wait(0.1)
end
while true do
local target = findNearestTarget()
if target then
walkWithPath(target.Position)
elseif (root.Position - START_POSITION).Magnitude > 3 then
walkWithPath(START_POSITION) -- 近くに誰もいなければ、壁をよけて元の場所へ戻る
else
task.wait(0.5)
end
end
上のタブに「HorrorService」(画像の2)が開き、コードが入りました。エクスプローラでは、ServerScriptServiceの中にHorrorService(画像の1)があります。

| コードの部分 | していること |
|---|---|
| CHASE_RANGE = 25 | 怪物から25スタッドより近い人だけを追いかける(スタッドはRobloxの長さの単位) |
| humanoid.WalkSpeed = 13 | 怪物の速さ。プレイヤーの16より少し遅い |
| findNearestTarget | いちばん近くにいて、体力があり、まだ脱出していない人を探す |
| onMonsterTouched | 怪物に触れた人の体力を0にし、その人の画面へ「caught」を送る |
| key.Touched | カギに触れた人に「HasKey(カギを持っている)」の印を付け、カギを見えなくする |
| exitDoor.Touched | 印のある人ならドアを透かして通れるようにし、ない人には「カギがかかっている…」を送る |
| goal.Touched | ゴールに着いた人に「Escaped(脱出した)」の印を付け、「escaped」を送る |
| walkWithPath | 壁をよけて行き先まで歩く道を計算する |
| 最後の while | 近くに人がいれば追いかけ、いなければ壁をよけて最初の場所へ戻る |
| lastDoorMessage | ドアに体を押しつけたままでも、「カギがかかっている…」を送るのは3秒に1回にする |
怪物を壁ぞいに歩かせる経路探索(PathfindingService)は、追いかけてくる敵の作り方の6で、壁がないときとあるときを比べながら解説しています。
6. 画面に文字と赤い画面を出すスクリプトを入れる
LocalScriptは、サーバーではなく、それぞれのプレイヤーのパソコンで動くスクリプトです。画面に文字を出すのはプレイヤーごとなので、LocalScriptを使います。
エクスプローラの「StarterPlayer」の左の「▶」を押して開き、中の「StarterPlayerScripts」にマウスを乗せて「+」を押します。一覧の検索欄に「LocalScript」と入れて、一覧の「LocalScript」を押します。入ったLocalScriptが選ばれた状態でF2キーを押し、「HorrorClient」と入れてEnterキーを押します。
エクスプローラのHorrorClientをダブルクリックして開きます。中身を全部消して、次のコードを貼り付けます(コードの画面の中を押してからCtrl + Aキーで全部選び、Deleteキーで消します)。
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local SoundService = game:GetService("SoundService")
local horrorEvent = ReplicatedStorage:WaitForChild("HorrorEvent")
local player = Players.LocalPlayer
local scream = SoundService:WaitForChild("Scream")
-- 画面に出す文字と、つかまったときの赤い画面を作る
local gui = Instance.new("ScreenGui")
gui.Name = "HorrorGui"
gui.ResetOnSpawn = false -- 倒れても画面を消さない
gui.IgnoreGuiInset = true -- 画面のいちばん上まで覆う
gui.Parent = player:WaitForChild("PlayerGui")
local message = Instance.new("TextLabel")
message.Size = UDim2.new(1, 0, 0, 60)
message.Position = UDim2.new(0, 0, 0.75, 0)
message.BackgroundTransparency = 1
message.TextColor3 = Color3.fromRGB(255, 255, 255)
message.TextStrokeTransparency = 0
message.TextScaled = true
message.Text = ""
message.Parent = gui
local scare = Instance.new("TextLabel")
scare.Size = UDim2.new(1, 0, 1, 0)
scare.BackgroundColor3 = Color3.fromRGB(120, 0, 0)
scare.TextColor3 = Color3.fromRGB(255, 255, 255)
scare.TextScaled = true
scare.Text = "つかまった!"
scare.Visible = false
scare.Parent = gui
-- 文字を3秒だけ出す
local function showMessage(text)
message.Text = text
task.delay(3, function()
if message.Text == text then
message.Text = ""
end
end)
end
horrorEvent.OnClientEvent:Connect(function(kind, text)
if kind == "message" then
showMessage(text)
elseif kind == "caught" then
scream:Play()
scare.Visible = true
task.wait(2)
scare.Visible = false
elseif kind == "escaped" then
showMessage("脱出成功!おめでとう")
end
end)
上のタブに「HorrorClient」(画像の2)が開き、エクスプローラのStarterPlayerScriptsの中にHorrorClient(画像の1)があります。

| コードの部分 | していること |
|---|---|
| ScreenGui・TextLabel を作る | 下のほうに出す文字と、画面いっぱいの赤い「つかまった!」をコードで作る(ScreenGuiは画面に重ねて出す板、TextLabelは文字を出す部品) |
| ResetOnSpawn = false | つかまってスタートに戻っても、画面の部品を消さない |
| showMessage | 文字を3秒だけ出して消す |
| "caught" を受け取ったら | 叫び声を鳴らし、赤い画面を2秒出す |
| "escaped" を受け取ったら | 「脱出成功!おめでとう」を出す |
画面の部品をStarterGuiに手で並べるやり方はボタンの作り方で解説しています。この記事では出す画面が2つだけなので、コードで作っています。
7. 懐中電灯を作る
Toolは、アバターが手に持って使う道具の入れ物です。StarterPackに入れた道具は、ゲームが始まると全員の持ち物に入ります。
エクスプローラの「StarterPack」にマウスを乗せて「+」を押します。一覧の検索欄に「Tool」と入れて、一覧の「Tool」を押します。入ったToolが選ばれた状態でF2キーを押し、「Flashlight」と入れてEnterキーを押します(下の画像の上の赤い枠)。
Flashlightを選んだ状態で、プロパティの検索欄に「ToolTip」と入れます。ToolTipの欄に「クリックで明かりをつける・消す」と入れて、Enterキーを押します(下の赤い枠)。ToolTipは、持ち物の欄にマウスを乗せたときに出る説明の文字です。

続けて検索欄に「CanBeDropped」と入れ、CanBeDroppedの右の四角を押してチェックを外します。チェックが入っていると、Backspaceキーで懐中電灯を落としてしまいます。(画像の1が選んでいるFlashlight、画像の2がCanBeDropped)

次に、手に持つ部分を作ります。エクスプローラの「Flashlight」にマウスを乗せて「+」を押し、一覧の検索欄に「Part」と入れて「Part」を押します。入ったPartが選ばれた状態でF2キーを押し、「Handle」と入れてEnterキーを押します(下の画像の上の赤い枠)。名前は大文字のHで始まる「Handle」にします。Toolの中のHandleという名前のパーツを、アバターが右手に持ちます。
Handleを選んだ状態で、プロパティの検索欄に「Size」と入れ、Sizeの欄に「0.6, 0.6, 2」と入れてEnterキーを押します(下の赤い枠)。

続けて検索欄に「Color」と入れ、Colorの欄の右の数字の部分を押して「30, 30, 30」と入れ、Enterキーを押します。黒い懐中電灯になります。手に持って動かす部品なので、Anchoredにはチェックを入れません。(画像の1が選んでいるHandle、画像の2がColor)

Handleにマウスを乗せて「+」を押し、一覧の検索欄に「SpotLight」と入れて「SpotLight」を押します(下の画像の上の赤い枠)。SpotLightは、懐中電灯のように一方向だけを照らす明かりです。
SpotLightを選んだ状態で、プロパティを下の表のように変えます。変えたあとの欄は、下の画像の赤い枠のようになります。

| プロパティ | この記事の値 | 意味 |
|---|---|---|
| Brightness | 5 | 明るさ |
| Range | 45 | 光が届く長さ(スタッド) |
| Angle | 50 | 光の広がり(度)。小さいほど細い光 |
| Enabled | チェックを外す | 最初は明かりを消しておき、クリックで付ける |
| Face | Front | パーツのどの面から照らすか |
- プロパティの検索欄に「Brightness」と入れ、Brightnessの欄に「5」と入れてEnterキーを押します。
- 検索欄に「Range」と入れ、Rangeの欄に「45」と入れてEnterキーを押します。
- 検索欄に「Angle」と入れ、Angleの欄に「50」と入れてEnterキーを押します。
- 検索欄に「Enabled」と入れ、Enabledの右の四角を押してチェックを外します。
- 検索欄に「Face」と入れ、Faceが「Front」になっていることを確かめます。SpotLightのFaceは最初から「Front」です。
最後に、エクスプローラの「Flashlight」にマウスを乗せて「+」を押し、一覧の検索欄に「Script」と入れて「Script」を押します。入ったScriptが選ばれた状態でF2キーを押し、「FlashlightScript」と入れてEnterキーを押します(下の画像の上の赤い枠)。
FlashlightScriptを選んだ状態で、プロパティの検索欄に「RunContext」と入れます。▼動作 の下のRunContextの欄を押して、一覧から「Server」を選びます(下の赤い枠)。

エクスプローラのFlashlightScriptをダブルクリックして開きます。中身を全部消して、次のコードを貼り付けます(コードの画面の中を押してからCtrl + Aキーで全部選び、Deleteキーで消します)。
local tool = script.Parent
local light = tool:WaitForChild("Handle"):WaitForChild("SpotLight")
-- クリックするたびに、明かりを付けたり消したりする
tool.Activated:Connect(function()
light.Enabled = not light.Enabled
end)
Activatedは、道具を手に持っているときにクリックした合図です。クリックのたびに、SpotLightのEnabled(付いているか)を反対にします。サーバーで明かりを変えるので、ほかのプレイヤーの画面でも明かりが付いたり消えたりします。
8. 叫び声の音を入れる
上の「ホーム」タブの「ツールボックス」(画像の1)を押すと、左にツールボックスが開きます。「オーディオ」(画像の2)を押します。

検索欄に「scream」と入れてEnterキーを押します(画像の1)。叫び声の効果音が並びます。編集部は、撮影のときにいちばん上に出た「Scary scream」(画像の2)を使いました。並び順は日によって変わります。

使う音の行を右クリックし、「アセットIDをコピー」(赤い枠)を押します。

ツールボックスは、ツールボックスの窓の右上の「×」を押して閉じます。
エクスプローラの「SoundService」にマウスを乗せて「+」を押します。一覧の検索欄に「Sound」と入れて、一覧の「Sound」を押します。入ったSoundが選ばれた状態でF2キーを押し、「Scream」と入れてEnterキーを押します(下の画像の上の赤い枠)。
Screamを選んだ状態で、プロパティの検索欄に「SoundId」と入れます。SoundIdの欄を押して、「rbxassetid://」と打ったすぐあとに、Ctrl + Vキーでコピーした数字を貼り付けて、Enterキーを押します(下の赤い枠)。この記事の音なら「rbxassetid://140028279221307」です。SoundIdのすぐ下のPreviewの緑の再生ボタン(3の番号)を押すと、編集画面のまま試しに聞けます。

音の探し方と、音の置き場所による聞こえ方のちがいは音楽と効果音を入れる方法で解説しています。
9. 館を真っ暗にする
エクスプローラの「Lighting」(画像の1)を押します。Lightingは、作品全体の時刻や明るさを決める場所です。Lightingを選んだ状態で、プロパティの検索欄に「ClockTime」と入れます。ClockTimeの欄に「0」と入れて、Enterキーを押します(画像の2)。時刻が夜中の0時になり、空と館が暗くなりました。

続けてLightingを選んだまま、検索欄に「Brightness」と入れます。Brightnessの欄に「0」と入れて、Enterキーを押します(赤い枠)。

最後に検索欄に「Ambient」と入れます。「Ambient」と「OutdoorAmbient」の2つが出ます。Ambientの欄の右の数字の部分を押して「15, 15, 15」と入れ、Enterキーを押します。OutdoorAmbientも同じように「15, 15, 15」にします(赤い枠)。この2つは、明かりが当たっていない場所の明るさです。最初の「70, 70, 70」のままだと、夜でも壁がうっすら見えます。15にすると、光るカギ以外はほとんど見えなくなりました。

| プロパティ | 最初の値 | この記事の値 | 変わること |
|---|---|---|---|
| ClockTime | 14.5 | 0 | 時刻。0は夜中 |
| Brightness | 3 | 0 | 太陽や月の光の強さ |
| Ambient | 70, 70, 70 | 15, 15, 15 | 屋根の下など、光が当たらない場所の明るさ |
| OutdoorAmbient | 70, 70, 70 | 15, 15, 15 | 外の、光が当たらない場所の明るさ |
暗すぎて作りにくいときは、作っている間だけLightingのClockTimeを「14.5」に戻し、テストの前に「0」にします。Lightingのほかの値は夜にする方法で解説しています。
10. テストで遊んで確かめる
以下は、アソビシフト編集部が2026年10月21日にテストで確かめた結果です。
3D画面の上の作品のタブ「Place1」を押して3D画面に戻り、F5キーでテストを始めます(タブの名前はパソコンによって違います)。画面の左上の「テスト」の右にある青い再生ボタン(赤い枠)を押しても始められます。

懐中電灯で照らす
テストを始めると、館の中は真っ暗です。画面の下に「Flashlight」の四角が出ています。キーボードの1キーを押すか、Flashlightの四角を押すと、懐中電灯を手に持ちます。手に持っている間は、Flashlightの四角に青い枠が付きます。
下の画像は、テストを始めて1キーで懐中電灯を持った直後の画面です(赤い枠がFlashlight)。持った直後は、まだ明かりは消えています。

懐中電灯を持ったまま3D画面をクリックすると、明かりが付いて前の壁が照らされます。下の画像は、テスト中にクリックして明かりを付けたところです。青い枠の付いたFlashlight(画像の1)を持ったまま、れんがの壁(画像の2)が照らされています。もう一度クリックすると消えます。

カギを拾う
WASDキーで歩き、南の部屋の右(東)のすき間から、まん中の部屋へ進みます。下の画像は、テスト中にまん中の部屋へ入ったところです。左(西)の奥に、黄色く光るカギ(赤い枠)が見えます。

カギに触れるとカギが消えて、画面の下に「カギを手に入れた!出口のドアへ行こう」と3秒出れば成功です。下の画像は、テストでカギに触れた直後の画面です。

カギなしでドアに触れる・怪物に追われる
カギを持たずに出口のドアへ触れると、ドアは開かず「カギがかかっている…」と出ます。カギを拾ったあとにこれを確かめるときは、Shift + F5キーでテストを停止してから、F5キーでテストを始め直します(始め直すとカギは元の場所に戻ります)。下の画像は、カギを持たずにドアへ触れたときのテストの画面です。

北の部屋の怪物に近づくと、奥から「???」の怪物が追いかけてきます。下の画像は、テスト中に怪物(赤い枠)が近づいてきたところです。

怪物に触れると、叫び声が鳴り、画面が赤くなって「つかまった!」と2秒出ます。下の画像は、テストで怪物に触れたときの画面です。

数秒後に、スタートの南の部屋から始め直しになります。怪物も、壁をよけて最初の場所へ戻ります。生き返ると懐中電灯の明かりは消えた状態に戻るので、もう一度クリックして付けます。一度拾ったカギは、つかまっても持ったままです。
脱出する
カギを持って出口のドアに触れると、ドアが透けて通れるようになります。外の緑の床に乗って「脱出成功!おめでとう」と出れば完成です。脱出したあとは、怪物は追いかけてきません。下の画像は、テストで緑の床に乗ったときの画面です。

確かめたら、Shift + F5キーでテストを停止します。
うまく動かないときの直し方
| こまったこと | 確かめる場所 | 直し方 |
|---|---|---|
| 怪物が動かない | 出力の文字 | 「Monster のパーツの Anchored を外してください」と出ていたら、HumanoidRootPart の Anchored のチェックを外す |
| 怪物が追ってこない | 名前 | エクスプローラの名前が「Monster」(大文字のM)か確かめる |
| 文字が出ない | HorrorEvent と HorrorClient | HorrorEvent が ReplicatedStorage に、HorrorClient が StarterPlayerScripts にあるか |
| カギに触れても何も起きない | Key の名前と CanTouch | 名前が「Key」か、CanTouch にチェックが入っているか |
| 懐中電灯が光らない | Handle と SpotLight | 名前が「Handle」か、SpotLight が Handle の中にあるか。持ったあとに3D画面をクリックしたか |
| 叫び声が鳴らない | Scream の SoundId | 「rbxassetid://」のあとが数字だけか、Preview で鳴るか |
| 暗すぎて何も見えない | Lighting の Ambient | 15 より大きい数にすると明るくなる |
もっと怖くする工夫
下の値は、変えると何が変わるかの目安です(編集部はこの値でのテストはしていません)。
| 変えるところ | 値の例 | 変わること |
|---|---|---|
| HorrorService の humanoid.WalkSpeed | 13 → 15 | 怪物が速くなり、逃げにくくなる |
| HorrorService の CHASE_RANGE | 25 → 40 | 遠くからでも気づかれる |
| SpotLight の Range | 45 → 25 | 懐中電灯の光が短くなり、先が見えにくい |
| Lighting の Ambient | 15 → 5 | さらに暗くなる |
| 怪物の Humanoid の DisplayDistanceType | None にする | 頭の上の「???」が出なくなり、どこにいるか分かりにくい(DisplayName を空にすると、名前の代わりにモデルの名前「Monster」が出る) |
数字を変えたら、そのたびにテストをして、怖さと遊びやすさのちょうどよいところを探します。怖すぎてゴールできないゲームは、遊んだ人がすぐにやめてしまいます。
AIに相談するときの伝え方
足したい仕掛けを、今のスクリプトの名前と一緒に伝えると、そのまま使えるコードが返ってきやすくなります。
Roblox Studioでホラーゲームを作っています。
ServerScriptServiceのHorrorServiceで、怪物(workspace.Monster)が近くのプレイヤーを追いかけています。
怪物がプレイヤーを見つけた瞬間に、そのプレイヤーにだけ心臓の音を鳴らしたいです。
HorrorEvent(ReplicatedStorageのRemoteEvent)を使い、HorrorClient(LocalScript)で鳴らす方法を教えてください。
よくある質問
友だちと一緒に遊べる?
遊べます。ただし、この記事のカギと出口のドアは全員で1つです。だれか1人がカギを拾うと、カギは消えて、ほかの人は拾えなくなります。ドアも、カギを持った人が触れると全員に開きます。1人ずつカギを拾わせたいときは、key.Touched の中の「key.Transparency = 1」と「key.CanTouch = false」の2行を消します。ドアを人ごとに開けたいときは、ドアの開け閉めを各プレイヤーの画面(LocalScript)で行う仕組みが別に必要です。2人で遊ぶテストのやり方は鬼ごっこの作り方と同じです。
怪物の見た目を変えたい
Monsterの中に「Humanoid」と「HumanoidRootPart」があれば、見た目を変えても同じコードで動きます。ブロック型アバターのまま、パーツの色や大きさを変えるのがいちばん簡単です。
次は、AIで作った車体で、周回とベストタイムを数えるレースゲームを作ります。次のステップ(上級 12/42)
次に知りたいことを選ぶ
- 次のステップ:AIで作った車体で、周回とベストタイムを数えるレースゲームを作ります → ロブロックス(Roblox)のレースゲームの作り方
- 追ってくる敵のしくみをおさらいしたい → 追いかけてくる敵の作り方
- 夜や明かりをもっと作り込みたい → 夜にする方法
- 手に持つ道具の作り方を知りたい → 手に持てるアイテムの作り方









