You can use CFrame.lookAt(at, lookAt) to get an NPC to look at a point.
-- in a loop,
NPC:SetPrimaryPartCFrame(CFrame.lookAt(
-- start at the NPC's position
NPC.HumanoidRootPart.Position,
-- makes the NPC look at the player, but not move up and down
Character.HumanoidRootPart.Position * Vector3.new(1,0,1)
+ NPC.HumanoidRootPart.Position * Vector3.new(0,1,0)
))
I hope that’s enough info.
Edit: this one is better cleaned up.
local NPCroot = NPC.HumanoidRootPart
local CharRoot = Character.HumanoidRootPart
NPC:SetPrimaryPartCFrame(CFrame.lookAt(
NPCroot.Position,
CharRoot.Position * Vector3.new(1, 0, 1)
+ NPCroot.Position * Vector3.new(0, 1, 0)
))