Roblox Studioで追いかけてくるNPCを作る方法【鬼ごっこ対応】
コラムRoblox Studio(ロブロックススタジオ)で鬼ごっこやゾンビサバイバルのようなゲームを作っていて、「NPCをプレイヤーに向かって走らせたいのに、思うように動かない」と悩んでいませんか。
ツールボックスからキャラクターを配置しただけでは、NPCはその場に突っ立ったままです。動かすにはスクリプトで「プレイヤーの位置を追いかけ続ける」処理を書く必要があり、ここでつまずく人が少なくありません。
この記事では、コピペで動くLuauコード付きで、基本のMoveTo方式から、障害物をかわして追いかけるPathfindingService方式まで2段階で解説します。追いかけBGMの付け方や、NPCが止まってしまうときの対処法もまとめているので、初めてスクリプトに触れる方でも鬼ごっこゲームを完成させられます。
Roblox公式のCreator Hub(create.roblox.com/docs)が公開しているPathfindingServiceのリファレンスをもとにしているので、情報の古さを気にせず読み進められます。
目次
- 追いかけてくるNPCとは?どんなゲームに使える?
- 鬼ごっこ・ゾンビ・警察ゲームへの応用
- 【基本】MoveToでNPCをプレイヤーに向かわせる
- NPCの準備(ツールボックスからRigを配置)
- スクリプトのコピペ手順
- 動作確認とよくあるミス
- 【応用】PathfindingServiceで障害物もかわして追いかける
- PathfindingServiceの基本セット
- スクリプト例と解説
- 追いかけBGM・効果音を鳴らして怖くする
- SoundServiceへの音源追加
- NPC接近時に音を鳴らすスクリプト
- 鬼ごっこゲームに仕上げる
- タグ判定・鬼交代の仕組み
- よくあるトラブルと対処法
- NPCが追いかけてこない
- NPCが途中で止まる
- よくある質問(FAQ)
- まとめ
追いかけてくるNPCとは?どんなゲームに使える?
追いかけてくるNPCとは、プレイヤーの位置をスクリプトで常に監視し、その方向へ向かって移動し続けるキャラクターのことです。Roblox Studioでは、ツールボックスから見た目のRigを配置しただけでは動かないため、「プレイヤーの座標を取得する」「その方向に移動する」処理を自分でスクリプトに書く必要があります。
鬼ごっこ・ゾンビ・警察ゲームへの応用
追いかけてくるNPCの仕組みは、そのまま次のようなゲームジャンルの土台になります。
- 鬼ごっこゲーム:鬼役のNPC(または他プレイヤー)が捕まえに来る
- ゾンビサバイバルゲーム:ゾンビの群れがプレイヤーを追跡する
- 警察ゲーム:捕まえると逮捕されるNPCが街を巡回して追いかけてくる
どのジャンルも「NPCがプレイヤーを追いかける」という同じロジックの上に、演出やルールを足しているだけです。次の章から、実際に動くコードを見ていきます。
【基本】MoveToでNPCをプレイヤーに向かわせる
一番シンプルなのが、HumanoidのMoveToメソッドを使う方法です。障害物のない開けたマップであれば、この方法だけで十分に動きます。
NPCの準備(ツールボックスからRigを配置)
Robloxのツールボックスで「Rig」と検索すると、腕や脚が動く人型モデルが見つかります。好きなRigをワークスペースに配置し、名前を「ChaseNPC」に変更しておいてください。RigにはHumanoidオブジェクトが最初から含まれているので、自分で追加する必要はありません。
スクリプトのコピペ手順
「ChaseNPC」の中にScriptを1つ追加し、以下のコードを貼り付けます。
local Players = game:GetService("Players")
local npc = script.Parent
local humanoid = npc:WaitForChild("Humanoid")
local rootPart = npc:WaitForChild("HumanoidRootPart")
while true do
task.wait(0.5)
local nearestPlayer = nil
local shortestDistance = math.huge
for _, player in ipairs(Players:GetPlayers()) do
local character = player.Character
if character then
local targetRoot = character:FindFirstChild("HumanoidRootPart")
if targetRoot then
local distance = (targetRoot.Position - rootPart.Position).Magnitude
if distance < shortestDistance then
shortestDistance = distance
nearestPlayer = targetRoot
end
end
end
end
if nearestPlayer then
humanoid:MoveTo(nearestPlayer.Position)
end
end
0.5秒ごとにプレイヤー全員との距離を測り、一番近いプレイヤーの座標へMoveToで移動を指示しています。複数人がいるゲームでも、常に最も近い相手を追いかける動きになります。
動作確認とよくあるミス
Playボタンでテストし、NPCがプレイヤーの方向へゆっくり歩き出せば成功です。動かない場合は、次の2点を確認してください。
- Scriptを置いた場所が「ChaseNPC」の直下になっているか(他のパーツの中に入れると`script.Parent`がずれる)
- Humanoidの`WalkSpeed`が0になっていないか(プロパティ画面で確認できる)
task.wait(0.5)の間隔を短くしすぎるとサーバー負荷が上がるため、まずは0.5秒から試して、必要に応じて調整してください。

【応用】PathfindingServiceで障害物もかわして追いかける
MoveToだけだと、NPCと目的地の間に壁があると、そこにぶつかって止まってしまいます。壁や建物のあるマップで追いかけっこをさせたいなら、PathfindingServiceを使って迂回ルートを計算させます。
PathfindingServiceの基本セット
PathfindingServiceは、マップ上の障害物を避けた経路(パス)を自動で計算してくれるRoblox公式のサービスです。まず先頭にサービスを呼び出します。
local PathfindingService = game:GetService("PathfindingService")
スクリプト例と解説
先ほどのMoveTo部分を、経路探索を使った関数に置き換えます。
local PathfindingService = game:GetService("PathfindingService")
local Players = game:GetService("Players")
local npc = script.Parent
local humanoid = npc:WaitForChild("Humanoid")
local rootPart = npc:WaitForChild("HumanoidRootPart")
local function chaseWithPathfinding(targetPosition)
local path = PathfindingService:CreatePath({
AgentRadius = 2,
AgentHeight = 5,
AgentCanJump = true,
})
local success = pcall(function()
path:ComputeAsync(rootPart.Position, targetPosition)
end)
if not success or path.Status ~= Enum.PathStatus.Success then
return
end
for _, waypoint in ipairs(path:GetWaypoints()) do
if waypoint.Action == Enum.PathWaypointAction.Jump then
humanoid.Jump = true
end
humanoid:MoveTo(waypoint.Position)
humanoid.MoveToFinished:Wait()
end
end
while true do
task.wait(1)
local nearestPlayer = nil
local shortestDistance = math.huge
for _, player in ipairs(Players:GetPlayers()) do
local character = player.Character
if character then
local targetRoot = character:FindFirstChild("HumanoidRootPart")
if targetRoot then
local distance = (targetRoot.Position - rootPart.Position).Magnitude
if distance < shortestDistance then
shortestDistance = distance
nearestPlayer = targetRoot
end
end
end
end
if nearestPlayer then
chaseWithPathfinding(nearestPlayer.Position)
end
end
path:ComputeAsync()で経由地点(ウェイポイント)の一覧を計算し、1つずつMoveToで辿らせています。壁を迂回する必要がある場合は自動でルートに反映されるため、NPCが壁にめり込んで止まる問題が起きにくくなります。処理が重くなりやすいので、経路の再計算は1秒に1回程度に抑えるのがおすすめです。

追いかけBGM・効果音を鳴らして怖くする
追いかける動きだけでも遊べますが、音を足すと臨場感が一気に上がります。ここではNPCがプレイヤーに近づいたときだけ音が鳴る仕組みを作ります。
SoundServiceへの音源追加
Roblox公式のライブラリ(Toolbox内の「Audio」タブ)からBGMや足音などの音源IDを探し、Soundオブジェクトとして「ChaseNPC」の中に配置します。名前は「ChaseSound」にしておきます。
NPC接近時に音を鳴らすスクリプト
MoveToのループの中に、距離判定を1行追加するだけで実装できます。
local chaseSound = npc:WaitForChild("ChaseSound")
local soundDistance = 15
local isPlaying = false
-- 距離判定用(whileループの中に追記する想定)
if nearestPlayer then
local distance = (nearestPlayer.Position - rootPart.Position).Magnitude
if distance <= soundDistance and not isPlaying then
chaseSound:Play()
isPlaying = true
elseif distance > soundDistance and isPlaying then
chaseSound:Stop()
isPlaying = false
end
end
soundDistance(スタッド数)を調整すると、音が鳴り始める距離を変えられます。値を大きくするほど、プレイヤーは早い段階でNPCの接近に気づけるようになります。
鬼ごっこゲームに仕上げる
追いかけるNPCができたら、あと少しの実装で鬼ごっこゲームとして完成します。
タグ判定・鬼交代の仕組み
NPCがプレイヤーに触れたら「鬼交代」として扱うには、Touchedイベントを使います。
rootPart.Touched:Connect(function(hit)
local character = hit.Parent
local player = Players:GetPlayerFromCharacter(character)
if player then
print(player.Name .. "がタッチされました!")
-- ここで鬼役の入れ替え処理や、捕まった演出を追加する
end
end)
このイベントが発火したタイミングで、捕まったプレイヤーにエフェクトを出したり、鬼NPCの役割を別のプレイヤーに移したりすれば、友達と遊べる鬼ごっこゲームに仕上がります。NPCが複数いる場合は、同じスクリプトを人数分コピーして配置すれば動きますが、人数が増えるほどサーバー負荷が上がるため、task.waitの間隔を長めに調整してください。

よくあるトラブルと対処法
コードは合っているはずなのに動かない、という相談で特に多いのが次の2つです。
NPCが追いかけてこない
HumanoidのWalkSpeedが0になっているか、スクリプトを置く場所が間違っているケースがほとんどです。ScriptはNPCモデルの直下に置き、script.ParentがNPC自身を指すようにしてください。プレイヤーが1人もゲームに参加していない状態でテストしていないかも確認しましょう。
NPCが途中で止まる
MoveTo方式だけを使っていると、壁や段差にぶつかった時点でNPCは止まってしまいます。この症状が出た場合は、PathfindingServiceを使った応用編のコードに切り替えてください。それでも止まる場合は、AgentCanJumpをtrueにしているか、段差の高さがRigのAgentHeightを超えていないかを確認します。
よくある質問(FAQ)
Q1. 追いかけてくるNPCはLuaが書けなくても作れますか?
ツールボックスの公式ゾンビモデルなど、あらかじめスクリプトが組み込まれたモデルを使えばコードなしで追跡NPCを配置できます。この記事のようにオリジナルの挙動にカスタマイズするにはスクリプトが必要です。
Q2. NPCが障害物にぶつかって止まります。どうすればいいですか?
PathfindingServiceを使うと、壁や建物があるマップでも迂回ルートを計算して追いかけてきます。記事内の「応用編」のスクリプトに差し替えてください。
Q3. 鬼ごっこゲームで鬼が1人だけでなく複数いるようにするには?
同じスクリプトを複数のNPCに配置すれば実現できます。ただしNPCの数が増えるとサーバー負荷が上がるため、task.waitの待機時間を長めに調整してください。
Q4. 追いかけられているときに怖い音楽を鳴らすにはどうすればいいですか?
SoundServiceにBGMや効果音を追加し、NPCとプレイヤーの距離が一定以下になったタイミングでSound:Play()を呼び出す方法で実装できます。記事内の「追いかけBGM」のセクションを参考にしてください。
Q5. 作った鬼ごっこゲームを友達と遊ぶ方法は?
Studio上の「テスト」タブからサーバーモードでの複数プレイヤー接続テストができます。実際に友達と遊ぶには「Publish to Roblox」でゲームを公開する必要があります。
まとめ
この記事では、Roblox Studioで追いかけてくるNPCを作る方法を解説しました。
重要なポイント:
- 開けたマップなら、Humanoidの`MoveTo`で最短距離のプレイヤーを追わせるだけで実装できる
- 壁や段差のあるマップでは、PathfindingServiceで迂回ルートを計算させる
- 距離判定を追加すれば、接近時だけ鳴る追いかけBGM・効果音を実装できる
- `Touched`イベントでタッチ判定を作れば、鬼ごっこゲームとして完成する
- NPCが止まる場合は、MoveToからPathfindingServiceへの切り替えを疑う
まずは基本のMoveTo方式から試して、NPCが動く感覚をつかんでみてください。慣れてきたら応用編のPathfindingServiceや、鬼ごっこのタッチ判定へと少しずつ機能を足していくと、無理なく1つのゲームとして完成させられます。
TETRA UPのRobloxコースでは、こうしたNPCの挙動づくりからゲームとしての完成まで、プロのインストラクターと一緒に手を動かしながら学べます。自分だけの鬼ごっこゲームを、実際に形にしてみませんか。
あわせて読みたい

吉田先生やよっしー、たまによしぞーって呼ばれたりしています。よろしくお願いします。