Hi I have an NPC which is basically going to be an AI. I made it where it can shoot at players which is great but I want to make it look at the players while its shooting them since right now he is stationary. How do I make him rotate at me?
How Do I Make A Model Of A NPC Look At The Player Constantly?
2 answers
keep setting the cframe of your npc's torso to face the player.
This is some sample code:
NPC:SetPrimaryPartCFrame(CFrame.new(NPC.PrimaryPart.Position,Player.Torso.Position))
**EDIT: Fixed it. Should now move the whole NPC.
4 comments
When I do this only the torso moves and not the whole NPC. So do I have to CFRAME move all the parts in the npc?
Ah, I forgot, you have to use model:SetPrimaryPartCFrame(). Updated my code.
What's the primary part. It's going to index a nil value
NVM Fixed it TYSM
This is by no means, "The Best Way". This is simply my way.
I'm be using a eye as representation for this tutorial. You should easily be able to apply this information to your situation.
Before continuing, my method doesn't use tables. This is a bit weird, and it might be able to be done better by using tables, but this was how I did it at the time.
First.
I'll be using a body gyro for this tutorial. Body Gyros are very useful and will help with our problem a lot, and they're much smoother. So first,
Let's define some variables,
local eye = script.Parent
local BG = script.Parent:WaitForChild("BodyGyro")-- BG Stands for Body Gyro.
Just defining variables
Second,
I'm going to use a while loop to look through the players and get their torsos. So second,
Setup a while loop,
local eye = script.Parent
local BG = script.Parent:WaitForChild("BodyGyro")
while wait() do
--Code later
end
You can use a while wait() do, with the wait, to simulate the same as putting the wait somewhere inside the loop.
Third,
I'm going to use a ipairs loop to iterate through the players. So third,
iterate through the players,
local eye = script.Parent
local BG = script.Parent:WaitForChild("BodyGyro")
while wait() do
for i,v in ipairs(game.Players:GetPlayers()) do
--Code Later
end
end
In our code later, we have a new variable called "v" that represents the player at the moment.
Fourth,
Now we need to get the character and the torso of the player. So fourth,
Get the character and torso,
local eye = script.Parent
local BG = script.Parent:WaitForChild("BodyGyro")
while wait() do
for i,v in ipairs(game.Players:GetPlayers()) do
local char = v.Character or v.CharacterAdded:wait()
local Torso = char:FindFirstChild("Torso") or char:WaitForChild("Torso")
end
end
Get the torso and character.
Fifth,
Now for the fun part! Lets make the eye face the direction of the player's torso! This is very easy if we use the body gyro! So fourth we,
Use the body gyro!
local eye = script.Parent
local BG = script.Parent:WaitForChild("BodyGyro")
while wait() do
for i,v in ipairs(game.Players:GetPlayers()) do
local char = v.Character or v.CharacterAdded:wait()
local Torso = char:FindFirstChild("Torso") or char:WaitForChild("Torso")
BG.CFrame = CFrame.new(eye.Position, Torso.Position)
end
end
Roblox wiki on Bodygyro.
Cool! This actually works now, but only for one person, and it doesn't check how far the player is from the eye. Here's a representation of it working.
Now we move onto my weird way of solving this. First, I make two new variables inside the ipairs loop,
local eye = script.Parent
local BG = script.Parent:WaitForChild("BodyGyro")
while wait() do
local Torso-- Main Torso
local num = math.huge
for i,v in ipairs(game.Players:GetPlayers()) do
local char = v.Character or v.CharacterAdded:wait()
local T = char:FindFirstChild("Torso") or char:WaitForChild("Torso")-- T stands for Torso.
BG.CFrame = CFrame.new(eye.Position, Torso.Position)
end
end
Added two new variables for manipulation later. Math.huge basically returns infinity.
Now I did an if statement to check if I should me the new torso the main torso by checking its distance from the eye compared to the others,
local eye = script.Parent
local BG = script.Parent:WaitForChild("BodyGyro")
while wait() do
local Torso--Main Torso
local num = math.huge
for i,v in ipairs(game.Players:GetPlayers()) do
local char = v.Character or v.CharacterAdded:wait()
local T = char:FindFirstChild("Torso") or char:WaitForChild("Torso")
local Mag = (T.Position - eye.Position).Magnitude
if Mag < num then-- Check to see if the new number is the new smallest number
num = Mag-- if it is, it changes the number.
Torso = T
end
end
end
Picks the lowest distance torso from the eye to be the main torso.
Last, but not least, I set the BodyGyro to the main torso after the ipairs loop, like so,
local eye = script.Parent
local BG = script.Parent:WaitForChild("BodyGyro")
while wait() do
local Torso
local num = math.huge
for i,v in ipairs(game.Players:GetPlayers()) do
local char = v.Character or v.CharacterAdded:wait()
local T = char:FindFirstChild("Torso") or char:WaitForChild("Torso")
local Mag = (T.Position - eye.Position).Magnitude
if Mag < num then
num = Mag
Torso = T
end
end
if Torso and num < 40 then-- the 40 is the field of view the eye has
BG.CFrame = CFrame.new(eye.Position, Torso.Position)
end
end
Simple if statement
But this still allows the eye to see you through walls and objects. The easiest way of fixing this is to use raycasting.
First, lets make our Ray,
local eye = script.Parent
local BG = script.Parent:WaitForChild("BodyGyro")
while wait() do
local Torso
local num = math.huge
for i,v in ipairs(game.Players:GetPlayers()) do
local char = v.Character or v.CharacterAdded:wait()
local T = char:FindFirstChild("Torso") or char:WaitForChild("Torso")
local Mag = (T.Position - eye.Position).Magnitude
if Mag < num then
local ray = Ray.new(eye.Position, (eye.Position - T.Position).unit * -500)-- Might change the -500 to 500.
num = Mag
Torso = T
end
end
if Torso and num < 40 then
BG.CFrame = CFrame.new(eye.Position, Torso.Position)
end
end
Sometimes the ray will fire backwards. If this happens, switch the negative to a positive.
Now we can choose what we want to ignore. This is easy. We're going to ignore the eye, the whatever the ray is firing from. Like so,
local eye = script.Parent
local BG = script.Parent:WaitForChild("BodyGyro")
while wait() do
local Torso
local num = math.huge
for i,v in ipairs(game.Players:GetPlayers()) do
local char = v.Character or v.CharacterAdded:wait()
local T = char:FindFirstChild("Torso") or char:WaitForChild("Torso")
local Mag = (T.Position - eye.Position).Magnitude
if Mag < num then
local ray = Ray.new(eye.Position, (eye.Position - T.Position).unit * -500)
local ignore = script.Parent--Ingnore
num = Mag
Torso = T
end
end
if Torso and num < 40 then
BG.CFrame = CFrame.new(eye.Position, Torso.Position)
end
end
Just defining ignore.
Now we can get what the ray hit by doing,
local eye = script.Parent
local BG = script.Parent:WaitForChild("BodyGyro")
while wait() do
local Torso
local num = math.huge
for i,v in ipairs(game.Players:GetPlayers()) do
local char = v.Character or v.CharacterAdded:wait()
local T = char:FindFirstChild("Torso") or char:WaitForChild("Torso")
local Mag = (T.Position - eye.Position).Magnitude
if Mag < num then
local ray = Ray.new(eye.Position, (eye.Position - T.Position).unit * -500)
local ignore = script.Parent
local hit = workspace:FindPartOnRay(ray, ignore)-- What the ray hit.
num = Mag
Torso = T
end
end
if Torso and num < 40 then
BG.CFrame = CFrame.new(eye.Position, Torso.Position)
end
end
Blah blah
Now all we have to do is check if what the ray hit is a descendant of the player's character. We can do this by using the IsDescendantOf function, like so,
local eye = script.Parent
local BG = script.Parent:WaitForChild("BodyGyro")
while wait() do
local Torso
local num = math.huge
for i,v in ipairs(game.Players:GetPlayers()) do
local char = v.Character or v.CharacterAdded:wait()
local T = char:FindFirstChild("Torso") or char:WaitForChild("Torso")
local Mag = (T.Position - eye.Position).Magnitude
if Mag < num then
local ray = Ray.new(eye.Position, (eye.Position - T.Position).unit * -500)
local ignore = script.Parent
local hit = workspace:FindPartOnRay(ray, ignore)
if hit:IsDescendantOf(char) then
num = Mag
Torso = T
end
end
end
if Torso and num < 40 then
BG.CFrame = CFrame.new(eye.Position, Torso.Position)
end
end
Checks for descendant or whatever.
And that's it!
Here's a demo of this working.
Good Luck!
If I helped, don't forget to accept my answer, it helps a lot.
2 comments
Just put the BodyGyro in the primary part and this should work.
Way to complex my guy.
This discussion is preserved as it was. New answers, comments, and votes are closed.

2 comments
Well, I know this was already solved but I have a simple way. make a head and put a script into it. after that you want to put this in the script: bin = script.Parent function move(target) local dir = (target.Position - bin.Position).unit local spawnPos = bin.Position local pos = spawnPos + (dir * 1) bin:findFirstChild("BodyGyro").cfra
Well to make the entire thing rotate I have a script that makes it so if the npc is anchored only the head moves. but I found that If I actually made it unanchored the entire thing would look at you! Ill post the script