Adjusting a Neck CFrame to the Direction another Part is Facing

Hello everybody. I’m currently making a script that can adjust the Neck.C0 value of a character to have his/her head rotate to face the same direction as a part in my workspace, named “AimPart”.

This code I have currently:

local Camera = workspace.CurrentCamera
local Player = game.Players.LocalPlayer

local Character = Player.Character
local Root = Character:WaitForChild("HumanoidRootPart")
local Neck = Character:FindFirstChild("Neck", true)
local YOffset = Neck.C0.Y

local CFNew, CFAng = CFrame.new, CFrame.Angles
local asin = math.asin

game:GetService("RunService").RenderStepped:Connect(function()
	local aimDirection = workspace.AimPart.CFrame.LookVector

    if Neck then
		if Character.Humanoid.RigType == Enum.HumanoidRigType.R15 then
        	Neck.C0 = CFNew(0, YOffset, 0) * CFAng(0, -asin(aimDirection.x), 0) * CFAng(asin(aimDirection.y), 0, 0)
		elseif Character.Humanoid.RigType == Enum.HumanoidRigType.R6 then
			Neck.C0 = CFNew(0, YOffset, 0) * CFrame.Angles(3 * math.pi/2, 0, math.pi) * CFAng(0, 0, -asin(aimDirection.x)) * CFAng(-asin(aimDirection.y), 0, 0)
		end
    end
end)

Produces this:

However, it only works when facing in one direction. Rotating the character in the second image to the left by 90 degrees produces this:
headToAimPart2

My question is how can I account for the angle the character is facing, and add that to my Neck CFrame? The result should have the character’s head face the same direction as the “AimPart” regardless of what direction the character is facing.

1 Like

I think I might know a potential solution to this, but I am at school right now and I will try to help with your code when I get home.
Edit: I have just got home and it looks like these two have pretty solid solutions.

1 Like

I was able to make the player face the block’s direction (even when the character is rotated)! However, I can’t explain it since I’m not familiar with CFrame operations. I referenced the player’s torso and multiplied some component of its orientation to the Neck’s CFrame.

wait(1)
local Camera = workspace.CurrentCamera
local Player = game.Players.LocalPlayer

local Character = Player.Character
local Root = Character:WaitForChild("HumanoidRootPart")
local Neck = Character:FindFirstChild("Neck", true)
local YOffset = Neck.C0.Y

local CFNew, CFAng = CFrame.new, CFrame.Angles
local asin = math.asin


game:GetService("RunService").RenderStepped:Connect(function()
	local aimDirection = workspace.AimPart.CFrame.LookVector
	
    if Neck then
		if Character.Humanoid.RigType == Enum.HumanoidRigType.R15 then
			local Torso = Character:FindFirstChild("UpperTorso", true)
        	Neck.C0 = CFNew(0, YOffset, 0) * CFAng(0, -asin(aimDirection.x), 0) * CFAng(asin(aimDirection.y), 0, 0)*CFAng(0,Torso.CFrame.LookVector.X,0)
		elseif Character.Humanoid.RigType == Enum.HumanoidRigType.R6 then
			local Torso = Character:FindFirstChild("Torso", true)
			Neck.C0 = CFNew(0, YOffset, 0) * CFrame.Angles(3 * math.pi/2, 0, math.pi) * CFAng(0, 0, -asin(aimDirection.x)) * CFAng(-asin(aimDirection.y), 0, 0)*CFAng(0,0,Torso.CFrame.LookVector.X)
		end
	end
end)

Hopefully this helps!

3 Likes

You need to offset the part’s CFrame rotation by the character’s CFrame rotation.

local partPointer = workspace.Part
local partRoot = character.HumanoidRootPart
local jointNeck = character.Head.Neck

game:GetService("RunService").Heartbeat:Conect(function()
    local off = partPointer.CFrame * partRoot.CFrame:Inverse() --subtract the character's CFrame
    off = off-off.Position                                     --get rid of the position offset
    jointNeck.C0 = off+jointNeck.C0.Position                   --apply to the neck with its current position offset
end)

Nice job! I see all you had to do was multiply by where the torso is looking on the X component. The only thing I added to what you have was I put local Torso outside of the Run Service function by doing:

local Torso = Character:FindFirstChild("HumanoidRootPart")

Thanks a lot!