体験申込で

Amazonギフト

カードもらえる

体験申込・無料相談

News

お知らせ

Roblox Studioで追いかけてくるNPCを作る方法【鬼ごっこ対応】

コラム

Roblox Studio(ロブロックススタジオ)で鬼ごっこやゾンビサバイバルのようなゲームを作っていて、「NPCをプレイヤーに向かって走らせたいのに、思うように動かない」と悩んでいませんか。

ツールボックスからキャラクターを配置しただけでは、NPCはその場に突っ立ったままです。動かすにはスクリプトで「プレイヤーの位置を追いかけ続ける」処理を書く必要があり、ここでつまずく人が少なくありません。

この記事では、コピペで動くLuauコード付きで、基本のMoveTo方式から、障害物をかわして追いかけるPathfindingService方式まで2段階で解説します。追いかけBGMの付け方や、NPCが止まってしまうときの対処法もまとめているので、初めてスクリプトに触れる方でも鬼ごっこゲームを完成させられます。

Roblox公式のCreator Hub(create.roblox.com/docs)が公開しているPathfindingServiceのリファレンスをもとにしているので、情報の古さを気にせず読み進められます。

追いかけてくる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点を確認してください。

  1. Scriptを置いた場所が「ChaseNPC」の直下になっているか(他のパーツの中に入れると`script.Parent`がずれる)
  2. Humanoidの`WalkSpeed`が0になっていないか(プロパティ画面で確認できる)

task.wait(0.5)の間隔を短くしすぎるとサーバー負荷が上がるため、まずは0.5秒から試して、必要に応じて調整してください。

Roblox StudioでNPCが一番近いプレイヤーをMoveToで追いかける仕組みを示す図解

【応用】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回程度に抑えるのがおすすめです。

Roblox StudioのPathfindingServiceが壁を迂回してNPCを追いかけさせる経路のイメージ図解

追いかけ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の間隔を長めに調整してください。

Roblox StudioでNPCがプレイヤーにタッチして鬼が交代する瞬間のイメージイラスト

よくあるトラブルと対処法

コードは合っているはずなのに動かない、という相談で特に多いのが次の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の挙動づくりからゲームとしての完成まで、プロのインストラクターと一緒に手を動かしながら学べます。自分だけの鬼ごっこゲームを、実際に形にしてみませんか。

あわせて読みたい

コラム