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)
However, it only works when facing in one direction. Rotating the character in the second image to the left by 90 degrees produces this:
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.
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.
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)
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")