I'm currently doing this, which works fine;
while true do
wait()
local plr = playerValue.Value
if plr then
local direction = (plr.Character.Torso.Position - bot.Torso.Position) * Vector3.new(1, 0, 1)
bot.Torso.CFrame = CFrame.new(bot.Torso.Position,bot.Torso.Position + direction)
end
end
with playerValue being an ObjectValue equal to the correct player.
However, with lots of NPCs this causes lots of lag. The Script Performance window shows that this is very inefficient, on a large scale at least.
Do you know any more efficient method of making the bot face your character?

3 comments
For some reason my walking around doesn't trigger the Changed event, but if I manually set the Position property it does trigger it. This is weird.
Odd. Maybe property is returning a Vector3 value instead of a string. I'll look into it.
Nope. Not sure what's up with it.