How would a joint follow camera's direction without being twisted by animations?

Hey,

What I would like to achieve is for player head & arms to properly follow camera. The problem I encountered is whenever I play animations that have horizontal rotation the joints that follow camera’s direction start twisting. I adjust the joints like this:

local angles = CFrame.Angles(camera.CFrame.LookVector.Y, 0, 0)
headJoint.C0 = CFrame.new(headJoint.C0.Position) * angles
rightArmJoint.C0 = CFrame.new(rightArmJoint.C0.Position) * angles
leftArmJoint.C0 = CFrame.new(leftArmJoint.C0.Position) * angles

How it looks in-game:

I assume the issue is that I’m applying the angle in object space instead of world space? Any support would be great!

Take care,
chiurly

Yes, joint CFrames are inherently object-space’d.

The problem is that with your current code, the Transform updates made my roblox animations will be calculated on top of the C0 you set. If I understood correctly what you want, then your rotation should be calculated on top of the Transform changes made by the animations.

This should work, as long as you replace the lines where neck, rShoulder and lShoulder are set (in the function connected to CharacterAdded).Those lines are currently written to work with r15 characters and your character is r6. Even if you don’t use this full code, remember to update Transform on stepped, otherwise the animations will override the changes.

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

local plr = Players.LocalPlayer
local cam = workspace.CurrentCamera

local neck, rShoulder, lShoulder


local function updateTransform()
	local angles = CFrame.Angles(cam.CFrame.LookVector.Y, 0, 0)
	local joints = {neck, rShoulder, lShoulder}
	for i, joint in ipairs(joints) do
		local animTransform = joint.Transform
		joint.Transform = animTransform*angles
	end
end

local diedConn, steppedConn
local function onDeath()
	diedConn:Disconnect()
	steppedConn:Disconnect()
end

plr.CharacterAdded:Connect(function(char)
	local hum = char:WaitForChild("Humanoid")
	-- Replace the next lines with correct references, they are written to work with r15 and your character is r6.
	neck = char:WaitForChild("Head"):WaitForChild("Neck")
	rShoulder = char:WaitForChild("RightUpperArm"):WaitForChild("RightShoulder")
	lShoulder = char:WaitForChild("LeftUpperArm"):WaitForChild("LeftShoulder")
	
	steppedConn = RunService.Stepped:Connect(updateTransform)
	diedConn = hum.Died:Connect(onDeath)
end)
2 Likes