Arm C0 still not adjusting for Torso Compensation

Good morning Devforum! I’ll get straight to the point. I have an issue with a script regarding arms pointing towards the mouse when torso rotations are involved. Here’s the script:

local player = game.Players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local mouse = player:GetMouse()

local torso = char:WaitForChild("Torso")
local root = char:WaitForChild("HumanoidRootPart")
local rightShoulder, leftShoulder, neck = torso:WaitForChild("Right Shoulder"), torso:WaitForChild("Left Shoulder"), torso:WaitForChild("Neck")

game:GetService("RunService").Stepped:Connect(function()
	
	local dir = torso.CFrame:ToObjectSpace(mouse.Origin).LookVector.Unit
	local rootLook = root.CFrame.LookVector
	local torsoLook = torso.CFrame.LookVector
	local angleFix = math.acos(math.clamp(rootLook:Dot(torsoLook),-1,1))

	rightShoulder.C0 = CFrame.new(1, 0.5, 0) * CFrame.Angles(0, angleFix, 0) * CFrame.Angles(math.asin(dir.Y), 0, 0) * CFrame.Angles(0, -angleFix, 0) * CFrame.Angles(0, math.pi / 2, 0)

	local offset = torso.CFrame * rightShoulder.C0 * (CFrame.new(-0.5, 0.5, 0) * CFrame.Angles(0, 
    math.pi / 2, 0)):Inverse() * CFrame.new(-3, 0, 0) * (CFrame.new(0.5, 0.5, 0))

	leftShoulder.C0 = torso.CFrame:ToObjectSpace(offset) * CFrame.Angles(0, -math.pi / 2, 0)
end)

It works fine, until an animation that moves the torso plays.
what1
what

As you can see, it moves on the yellow axis, however, I want it to move on the green axis. so if anyone knows how to fix this, I’d be happy. Also please note that the script works well when torso rotations aren’t involved.

I noticed where this code came from haha.

Honestly when the axis of rotation changes it’s usually due to the order of multiplication.

I do not know the fix but in this scenario I would rearrange the equation and see what happens (Trial and error)

For example changing the angle fix order maybe move angle fix after the math.pi?

IDK impossible for anyone else to help without access to the asset. CFrames are pain this way.

	rightShoulder.C0 = CFrame.new(1, 0.5, 0) * CFrame.Angles(0, angleFix, 0) * CFrame.Angles(math.asin(dir.Y), 0, 0) * CFrame.Angles(0, -angleFix, 0) * CFrame.Angles(0, math.pi / 2, 0)
--Perhaps this?
	rightShoulder.C0 = CFrame.new(1, 0.5, 0) * CFrame.Angles(0, angleFix, 0) * CFrame.Angles(math.asin(dir.Y), 0, 0) *CFrame.Angles(0, math.pi / 2, 0) * CFrame.Angles(0, -angleFix, 0) 

--Or even this?
	rightShoulder.C0 = CFrame.new(1, 0.5, 0) * CFrame.Angles(0, angleFix, 0) *CFrame.Angles(0, -angleFix, 0) * CFrame.Angles(math.asin(dir.Y), 0, 0) *CFrame.Angles(0, math.pi / 2, 0)  
2 Likes

Hey! Thanks for replying. You are absolutely right that CFrames are hard to work with without access to the thing that’s being fixed. I’ll try to rearrange the equation and I can give you the rblx file if you want.

1 Like

Nope too busy.

I would advice focusing on moving around the aim up and down term which is the one with dir.Y so everything to the left hand side of the equation is a suspect for messing up the angle of axis

rightShoulder.C0 = CFrame.new(1, 0.5, 0) * CFrame.Angles(0, angleFix, 0) * CFrame.Angles(math.asin(dir.Y), 0, 0) 

Also the right shoulder is based on the torso CFrame due to the weld equation so you might need to add something to counteract it other than the y axis of the angle fix. Perhaps using the animation transform root.Transform

local animationCounterCFrame = --IDK? Based on torso animations somehow. motor6d.Transform:Inverse()?
rightShoulder.C0 = CFrame.new(1, 0.5, 0) * CFrame.Angles(0, angleFix, 0) *animationCounterCFrame * CFrame.Angles(math.asin(dir.Y), 0, 0) 

1 Like

I appreciate your help! I will look into all of your suggestions. Thanks again.

1 Like

Bumping because I still haven’t found a solution.

Bump again. This has been bothering me for a while now.

hey i see that you’re using my script
i actually switched to using root transform implement this and see if it works
remove neck rotation if you want to

local dir = root.CFrame:ToObjectSpace(mouse.Origin).LookVector.Unit

local _, _, torsoZ = rootJoint.Transform:ToEulerAnglesXYZ()
local _, _, headZ = neck.Transform:ToEulerAnglesXYZ()

rightShoulder.C0 = CFrame.new(1, 0.5, 0) * CFrame.Angles(0, -torsoZ, 0) * CFrame.Angles(math.asin(dir.Y), 0, 0) * CFrame.Angles(0, torsoZ, 0) * CFrame.Angles(0, math.pi / 2, 0)
local offset = torso.CFrame * rightShoulder.C0 * LEFT_ARM_OFFSET
leftShoulder.C0 = torso.CFrame:ToObjectSpace(offset) * CFrame.Angles(0, -math.pi / 2, 0)

neck.C0 = CFrame.new(0, 1, 0) * CFrame.Angles(0, headZ, 0) * CFrame.Angles(math.asin(dir.Y), 0, 0) * CFrame.Angles(0, -headZ, 0) * CFrame.Angles(math.pi / 2, -math.pi, 0)
1 Like

I completely forgot about this, but it works perfectly. Thank you.