Im trying to make the NPCs head turn toward the player but it is looking the oposite way of the player?
local char = script.Parent
local hrp = char:WaitForChild("HumanoidRootPart")
local head = char:WaitForChild("Head")
local function findClosestsPlayerHrp(dist)
local closestHrp = nil
for i, v in pairs(game.Players:GetChildren()) do
local tChar = v.Character or v.CharacterAdded:Wait()
local tHrp = tChar:FindFirstChild("HumanoidRootPart")
if tHrp then
local tmpDist = (tHrp.Position - hrp.Position).Magnitude
if tmpDist < dist then
closestHrp = tHrp
dist = tmpDist
end
end
end
return closestHrp, dist
end
while wait() do
local closestHrp, dist = findClosestsPlayerHrp(100)
if closestHrp then
local dir = (closestHrp.Position - hrp.Position).Unit
local vecA = Vector2.new(dir.X, dir.Z)
local vecB = Vector2.new( hrp.CFrame.LookVector.X)
local dotProd = vecA:Dot(vecB)
local crossProd = vecA:Cross(vecB)
local angle = math.atan2(crossProd, dotProd)
local ht = closestHrp.Position.Y - hrp.Position.Y
local UpDwnAngle = math.atan(ht/dist)
head.CFrame = CFrame.new(head.Position) * CFrame.Angles(0, angle, 0)
* CFrame.Angles(UpDwnAngle, 0, 0)
if head.Orientation.Y >= 101 or head.Orientation.Y <= -101 then
head.Orientation = Vector3.new(0,0,0)
end
end
end
Your script is very hard to read. I went ahead and made a new version of your script with legible variables. It also works. Here it is:
local char = script.Parent
local npcRoot = char:WaitForChild("HumanoidRootPart")
local npcHead = char:WaitForChild("Head")
local function findClosestPlayerRoot(dist)
local closestRoot = nil
for i, player in pairs(game.Players:GetChildren()) do
local playerChar = player.Character or player.CharacterAdded:Wait()
local playerRoot = playerChar:FindFirstChild("HumanoidRootPart")
if playerRoot then
local newDist = (playerRoot.Position - npcRoot.Position).Magnitude
if newDist < dist then
closestRoot = playerRoot
dist = newDist
end
end
end
return closestRoot, dist
end
while true do
wait(0.5)
local closestRoot, dist = findClosestPlayerRoot(100)
if closestRoot then
-- #### all unnecessary, sorry......
--local direction = (closestRoot.Position - npcRoot.Position).Unit
--local vecA = Vector2.new(direction.X, direction.Z)
--local vecB = Vector2.new(npcRoot.CFrame.LookVector.X)
--local dotProd = vecA:Dot(vecB)
--local crossProd = vecA:Cross(vecB)
--local angle = math.atan2(crossProd, dotProd)
--local height = closestRoot.Position.Y - npcRoot.Position.Y
--local UpDownAngle = math.atan(height/dist)
npcHead.CFrame = CFrame.new(npcHead.Position, closestRoot.Position)
if npcHead.Orientation.Y >= 101 or npcHead.Orientation.Y <= -101 then
npcHead.Orientation = Vector3.new(0,0,0)
end
end
end
I did minimal changes to the code outside of the variables and a few tweaks. You can see I cut off a big chunk at the bottom. I did that because you went through a very complicated process to find the direction for the head to look at. Honestly, that is probably why your code wasn’t working. Simply too complicated to fix, let alone read.
Thankfully, if you do CFrame.new(), you can do a second parameter to define the position you want to look at. Here is an example:
CFrame.new(pos1,pos2) -- pos1 and pos2 are Vector3 values
Have a nice day. Please take the time to make your code easy to understand, for the sake of yourself and others.
Thanks, but the Npcs head is snapping and not moving smoothly like i had it before, and when i move to far to the right of it, it snaps to the other side?
P.S. You’ll want to figure out another way to update the head’s position. My recommendation: Don’t do a loop that runs forever. Instead, try running a script on the client that updates the head position whenever the player moves AND is within 100 studs of the NPC. That should get you much better performance.
Also, you got some problems with the npcHead orientation whenever you reset it AND continue the loop (check the code bit at the bottom). I’ll let you solve that one yourself.
Yes. I set the the loop to run every 0.5 seconds. Obviously, this is choppy, but all I wanted to demonstrate was that it was working. I recommend you find another way to run the loop besides just setting a wait() since it may cause performance issues.
Also, the head snapping when you move around it is because of the code snippet at the end, specifically this:
if npcHead.Orientation.Y >= 101 or npcHead.Orientation.Y <= -101 then
npcHead.Orientation = Vector3.new(0,0,0)
end
This happens because it will continue to update the head’s position, even when you are behind the NPC (because of your forever loop). It also happens because it will keep setting the CFrame of the head towards the player before checking if it will snap its neck. As a result, it snaps its neck over and over. Not very healthy if you ask me. Perhaps only set the position if they are in front, instead of correcting after it is already set?