Hello!
I have a script from a tutorial that is supposed to make a NPC’s head follow wherever you are. It works, but the way it does is just, weird… It snaps its head to where the player is instead of smoothly turning when it detects a player:
local char = script.Parent
local head = char:WaitForChild("Torso")
local hrp = char:WaitForChild("HumanoidRootPart")
local neck = char.Torso:WaitForChild("Neck")
local xOffSet = neck.C0.X
local yOffSet = neck.C0.Y
local zOffSet = neck.C0.Z
local function getClosestPlayerHrp(dist)
local closestHrp = nil
for i,v in ipairs(workspace:GetChildren()) do
local human = v:FindFirstChild("Humanoid")
local torso = v:FindFirstChild("Torso") or v:FindFirstChild("HumanoidRootPart")
if human and torso and v.Name ~= script.Parent.Name then
local tmpHrp = v:FindFirstChild("Torso") or v:FindFirstChild("HumanoidRootPart")
local tmpDist = (tmpHrp.Position - hrp.Position).Magnitude
if tmpHrp and tmpDist < dist then
closestHrp = tmpHrp
dist = tmpDist
end
end
end
return closestHrp, dist
end
while wait(0) do
local closestHrp, dist = getClosestPlayerHrp(10) --unit of studs
if closestHrp then
local cframe0 = neck.C0
local dir = (closestHrp.Position - hrp.Position).Unit
local vecA = Vector2.new(hrp.CFrame.LookVector.X, hrp.CFrame.LookVector.Z)
local vecB = Vector2.new(dir.X, dir.Z)
local dotValue = vecB:Dot(vecA)
local crossValue = vecB:Cross(vecA)
local ht = hrp.Position.Y - closestHrp.Position.Y
local upAngle = math.atan(ht/dist)
local angle = math.atan2(crossValue, dotValue)
if angle > math.pi/3 then
angle = math.pi/3
elseif angle < -math.pi/3 then
angle = -math.pi/3
end
neck.C0 = CFrame.new(neck.C0.Position) * CFrame.Angles(-upAngle, angle, 0) * CFrame.Angles(math.rad(-90), 0, math.rad(-180))
else
neck.C0 = CFrame.new(neck.C0.Position) * CFrame.Angles(math.rad(-90), 0, math.rad(-180))
end
end
Video:
How can I make it so that it doesn’t just snap into place?