Issue with head follow script for R6 npcs

What do you want to achieve?
I would like to make an R6 npcs head follow a player

What is the issue?
On R15 the script works fine but on R6 the npc looks down as if its head is broken

What solutions have you tried so far?
I changed some of the numbers on the script but they would make the head tilt sideways

local char = script.Parent
local head = char:WaitForChild("Head")
local hrp = char:WaitForChild("HumanoidRootPart")
local neck = char:WaitForChild('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 pairs(game.Players:GetChildren()) do
		local tmpChar = v.Character or v.CharacterAdded:Wait()
		local tmpHrp = tmpChar:FindFirstChild("HumanoidRootPart")
		local tmpDist = (tmpHrp.Position - hrp.Position).Magnitude      
		if tmpHrp and tmpDist < dist then
			closestHrp = tmpHrp
			dist = tmpDist
		end
	end
	return closestHrp, dist
end

while wait() do
	local closestHrp, dist = getClosestPlayerHrp(20)
	if closestHrp then
		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 = vecA:Dot(vecB)
		local crossValue = vecA:Cross(vecB)
		local ht = hrp.Position.Y - closestHrp.Position.Y
		local upAngle = math.atan(ht/dist)
		local angle = math.atan2(crossValue, dotValue)
		neck.C0 = CFrame.new(xOffSet, yOffSet, zOffSet)*CFrame.Angles(0, -angle, 0) * CFrame.Angles(-upAngle, 0, 0)
	end
end

I’m guessing this is the formula that works for R15:

neck.C0 = CFrame.new(xOffset, yOffset, zOffset) * CFrame.Angles(0, -angle, 0) * CFrame.Angles(0, 0, -upAngle)

This is the formula for R6 that I came up with using the video below as reference, but I don’t know why the head snaps to an odd position when you go behind the NPC:

neck.C0 = CFrame.new(xOffSet, yOffSet, zOffSet) * CFrame.Angles(3 * math.pi/2, 0, math.pi) * CFrame.Angles(0, 0, -math.asin(angle)) * CFrame.Angles(math.asin(upAngle), 0, 0)

If you want to give getting the correct formula for R6 another try, here’s the youtube video I watched a while ago that goes over head movement with R15 and R6. 3:40 is when the formula for R6 head movement is pasted in the video. You may have to watch some of the first video too to understand that things like his “CFAng” is just CFrame.Angles.

2 Likes