Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

how to make NPCs able to see players and fire an event?

IV BEEN WORKING ON THIS FOR YEARS. I STILL CANT FIND THE ANSWER. Kinds like the game on Roblox "Notoriety", where guards see you, and when they do it raises detection. I want that, but I'm so frustrated i can't find the answer. the other day finally I was given a clue. two clues actually.

One person said exactly this:

you can use camera.GetPartsObscuringTarget()

more here

someone else said exactly this:

You can raycast from the NPC's head to the target, if it hits a body part belonging to them, then the NPC sees them.
view source
1	local maximumDistance = 300 -- the ray's max distance, in studs
2	local ray = Ray.new(NPC.Head.Position, (TARGET.HumanoidRootPart.Position - NPC.Head.Position).Unit * maximumDistance)
3	local hit = workspace:FindPartOnRayWithIgnoreList(ray,{NPC})
4	 
5	if hit.Parent == target.Parent then
6	    print("i can see the player")
7	else
8	    print("i cannot see the player")
9	end

Keep in mind that I haven't tested the code above, so it may need some tweaking.

So I paid attention and spent some days trying to figure out how to use it. i looked it up in about 1000 different ways and looked everywhere on the internet, couldnt find my answer. then i spent hours and even more days trying to figure it out myself. trying things. i stilll havent figured it out. please help me, im DYING to know for a game im working on! thanks

2 comments

0

you have NO idea how overwhelmed and frusterated i am.

0

3 answers

✓ Accepted answer

You can use the dot product to see if the target is in front of the npc's face

local num = math.acos(NPC.Head.CFrame.LookVector:Dot((Target.HumanoidRootPart.Position-NPC.Head.Position).unit))

Then you can use a ray to see if the target is visible

local range = how close the npc needs to be to detect the target
local ray = Ray.new(NPC.Head.Position,(Target.HumanoidRootPart.Position-NPC.Head.Position).unit*range)
local part = workspace:FindPartOnRay(ray,NPC,true,true)
if part:FindFirstAncestor(Target.Name) then
	-- the npc can see the target
end

3 comments

0

oh god, thanks a lot!!!!! ill try this

0

doesnt work, i tried the ray thing only which should have worked, i tried many times, but for somereason, eventually it worked but the output started saying things like DYNAMIC LIGHTPOLE was something the ray was hitting, which i wasnt even 10 blocks in range of the dynamic light pole, and it barely works, it says "not spotted" so many times even when im not behind walls and stuff

0

ok i tried it agian it works! thx i was doing it wrong before

I still think Raycasting is the best option. In a loop, use the code you have to raycast a certain distance. Get the first part that the ray hits (see WorldRoot:GetPartOnRay()), and if it belongs to a player character then do your alert code.

1 comment

0

i tried , it doenst work

umm Synkrio, i tried this script inside my guard NPC

game.Players.PlayerAdded:Connect(function(plr)
	plr.CharacterAdded:Connect(function(i)
while true do
local range = 216
local ray = Ray.new(script.Parent.Head.Position, i.HumanoidRootPart.Position)
local part = workspace:FindPartOnRay(ray, script.Parent, true, true)
if part then
	print("spotted")
	local p = Instance.new("Part",workspace)
	p.Anchored = true
	p.Position = part.Position
	part:Destroy()
else
	print("not spotted yet")
end
wait()
end
end)
end)

but its doing weird stuff, i swear thats the only detection script i have, but it does REALLY weird things. it sometimes destroys my HEAD, never destroyed my humanoid root part, it even outputted "can not destroy terrain" which means somehow the ray detected TERRAIN even though its supposed to be aimed at my humanoidrootpart, and its like i have a range on it, but i dont, if i walk about 10 studs away from the NPC, no matter where i am, he doesnt detect me. HELP ME, whats going on!?

1 comment

0

local ray = Ray.new(script.Parent.Head.Position,(i.HumanoidRootPart.Position - script.Parent.Head.Position).unit*range)

This discussion is preserved as it was. New answers, comments, and votes are closed.