Detection Question (SOLVED)

So I have been wondering how I could make an NPC detect a player and execute code

I don’t think while loops will work as I want the code to execute once and I have tried other ways too

Is there any other way I can do this?

Edit: I should probably specify I want it so when the player gets close to the NPC code executes and if they get further away code executes

Edit 2: So I have basically tried to follow what JamalDequash said but I had some problems I put in a video: Magnitude Help - YouTube

The code (if U want to see it)

local Monster = workspace[" "]
local getplrs = game:GetService("Players"):GetPlayers()
local plr = game.Players.LocalPlayer
wait(1.5)
local char = plr.Character
local torso = char.HumanoidRootPart




while true do
	wait()
	local mag = (Monster.HumanoidRootPart.Position - torso.Position).magnitude
	if mag < 15 then
		print("Mag is greater")
	
	end

	if mag > 15 then	
		print("Mag is lesser")
	
	end
end


-- This is a local script btw
1 Like

When you say “detect”, do you mean if the NPC collides with the player?
In this case, you can test the NPC collision.

1 Like

I mean if you get close to the npc. The npc will start to walk to you

1 Like

You can create an invisible part surrounding the NPC and use a “touched” event for this part every time the player touches it.

1 Like

use touched() or sum like that if you want it to execute once
also debounce

get the npc and player’s position and use magnitude to check their distance

1 Like

I second @DeodorantSlice37 suggestion… get the humanoidrootparts position.magnitude of npc and of player, and if its less than a certain distance it executes function.

1 Like

Im not sure how I would use this but I made a vid explaining more on what I mean

vid: Magnitude Help - YouTube

The Code (in case if u wanted to know)

local Monster = workspace[" "]
local getplrs = game:GetService("Players"):GetPlayers()
local plr = game.Players.LocalPlayer
wait(1.5)
local char = plr.Character
local torso = char.HumanoidRootPart




while true do
	wait()
	local mag = (Monster.HumanoidRootPart.Position - torso.Position).magnitude
	if mag < 15 then
		print("Mag is greater")
	
	end

	if mag > 15 then	
		print("Mag is lesser")
	
	end
end


-- This is a local script btw



replying to bump this so more people see it…

1 Like

This just checks if the player is near the npc

local Dummy = script.Parent
local HumanoidRootPart = Dummy.HumanoidRootPart

local players = game:GetService("Players")

for i, player in pairs(players:GetPlayers()) do
	if player.Character then
		print(player:DistanceFromCharacter(HumanoidRootPart.Position))

		if player:DistanceFromCharacter(HumanoidRootPart.Position) < 20 then
			Dummy.Humanoid:MoveTo(player.character.HumanoidRootPart.Position)
		end
	end
end

ok i made some mistakes, now heres the working script

local Dummy = script.Parent
local HumanoidRootPart = Dummy.HumanoidRootPart

local players = game:GetService("Players")

for i, Parts in pairs(Dummy:GetChildren()) do
	if Parts:IsA("BasePart") then
		Parts:SetNetworkOwner(nil)
	end
end

while wait() do
	for i, player in pairs(players:GetPlayers()) do
		if player.Character then
			if player:DistanceFromCharacter(HumanoidRootPart.Position) < 20 then
				Dummy.Humanoid:MoveTo(Vector3.new(player.Character.HumanoidRootPart.Position.X - 5, player.Character.HumanoidRootPart.Position.Y, player.Character.HumanoidRootPart.Position.Z))
			end
		end
	end
end
1 Like

Literally in the toolbox, just search up “NPC follow”, and the first result will be what you want-

(I believe you want the NPC to follow the closest player.)

local Monster = workspace
local TriggerDistance = 15
local ChaseCutoffDistance = 20


local MonsterHrp = Monster:WaitForChild("HumanoidRootPart")
local Following = nil
while true do
	wait()
	if Following then
		if ((MonsterHrp.Position - Following[1].Position).Magnitude > ChaseCutoffDistance) or not (Following[2].Health > 0) then
			print("Stopped chasing")
			Following = nil
			continue
		end 
		-- Chase in loop
		print("Chasing: '"..Following[1].Parent.Name.."'")
		continue
	end
	for _, Player in pairs(game:GetService("Players"):GetPlayers()) do
		local Character = Player.Character
		if not Character then continue end
		local Humanoid = Character:FindFirstChild("Humanoid")
		if not Humanoid then continue end
		local Hrp = Character:FindFirstChild("HumanoidRootPart")
		if not Hrp then continue end
		if (MonsterHrp.Position - Hrp.Position).Magnitude > TriggerDistance then continue end
		if not Following then
			Following = {Hrp, Humanoid}
			print("Started chasing: '"..Player.Name.."'")
		end
	end
end

You can use a debounce:

local Monster = workspace[" "]
local InRange = false
local getplrs = game:GetService("Players"):GetPlayers()
local plr = game.Players.LocalPlayer
local char = plr.Character or plr.CharacterAdded:Wait()
local torso = char:WaitForChild("HumanoidRootPart")

game:GetService("RunService").Stepped:Connect(function()
	local mag = (Monster.HumanoidRootPart.Position - torso.Position).magnitude
	if mag <= 15 and not InRange then
		InRange = true
		print("NPC is in range")
	end

	if mag > 15 and InRange then
		InRange = false
		print("NPC is out of range")
	end
end)

This will make the code fire once when the NPC comes within 15 studs of the player and fire once when the NPC becomes further than 15 studs from the player.

1 Like

This works thank you dude!!!