I’m trying to make an NPC that moves towards the player when not being looked at by using Camera:WorldToScreenPoint() , but I don’t exactly know how to use it to make an NPC follow the player.
Also I am trying to handle this all inside of one script, but if it is two, that’s fine as well.
You could use raycasting to check if the player is looking at the NPC and than use pathfinding service to make the NPC walk towards the player if they are looking away
IMO it is too expensive to do that because it is a constant looped check for every player (efficiency). I think a smaller hitbox that is like an invisible accessory/welded part would be best with a listener on it. If someone is within that range - stop movement.
So have this Events and Script in your workspace, and a LocalScript in PlayerGui.
In Script paste:
local npc = workspace.Dummy -- Your NPC
local hum = workspace.Dummy:WaitForChild("Humanoid")
local head = workspace.Dummy:WaitForChild("Head")
while true do
wait(0.1)
local canmove = true
for i,player in ipairs(game.Players:GetChildren()) do
local islooking = workspace.Events.IsLookingAt:InvokeClient(player,head.Position)
if islooking == true then
if player.Character then
if player.Character.Humanoid.Health > 0 then
canmove = false
end
end
end
end
if canmove == false then
hum.WalkSpeed = 0
else
hum.WalkSpeed = 16 -- Speed of the NPC
end
end
and in LocalScript (in the PlayerGui) paste:
local plr = game.Players.LocalPlayer
function onevent(position)
local camera = workspace.CurrentCamera
local islooking = false
local _,isoncamera = camera:WorldToScreenPoint(position)
if isoncamera then
islooking = true
else
end
return islooking
end
workspace.Events.IsLookingAt.OnClientInvoke = onevent
Now in the script just change npc = workspace.Dummy to the NPC u want
ill give out the basics here
im doing all of this thru the npc’s movement script so none of this is local (i wont bother with that)
add this to your npc’s follow script
local head = script.Parent.Head
local HRP = script.Parent.HumanoidRootPart
local Hum = script.Parent.Humanoid
local FOV = 60 -- field of view of the player
local range = math.huge -- basically how far a player can look at the npc until they stop
local PlayerService = game:GetService("Players")
local function GetCharacters() -- will make it so other characters wont block out the npc from your fov
local Characters = {}
for _, b in PlayerService:GetPlayers() do
table.insert(Characters, b.Character)
end
return Characters
end
local function CheckLineOfSight(Start, End) -- raycasting, basically makes it so the npc isnt detected thru walls
local Params = RaycastParams.new()
Params.FilterDescendantsInstances = {script.Parent, GetCharacters()}
Params.FilterType = Enum.RaycastFilterType.Exclude
local Raycast = game.Workspace:Raycast(Start, End - Start, Params)
if Raycast then
return false
else
return true
end
end
function detectNpc(target)
local Character = target.Parent
if Character then
if Character.Head then
local NPCToCharacter = (head.Position - Character.Head.Position).Unit
local NPCLookVector = Character.Head.CFrame.LookVector
local DotProduct = NPCToCharacter:Dot(NPCLookVector)
local Angle = math.deg(math.acos(DotProduct))
local Distance = (Character.HumanoidRootPart.Position - HRP.Position).Magnitude
if Angle <= FOV and Distance <= range and CheckLineOfSight(Character.Head.Position, head.Position) then
Hum.WalkSpeed = 0
-- looked
else
Hum.WalkSpeed = 16
-- not looked
end
end
end
end
after that i just added detectNpc in a while loop to have more faster detection speed, although theres
probably a better way to do that.
i set the target to the player’s HRP
the result should probably be something like this:
Thank you very much for providing this. Could you kindly explain further how you implement this in the follow script because when I try using this in my current follow script, it only makes it follow the player once then once they look at the npc it just stops and never moves again.