How to translate CFrame relative to HumanoidRootPart to Motor6D C0 relative to Torso?

Apologies if the title isn’t the best.
For my game’s aiming system, I want to make the player’s arms aim towards wherever their cursor hits, similar to Guts & Blackpowder. I have achieved this exact effect using a custom rig, but that is unsatisfactory because most gears don’t work with it and I have to manually recode them.


Essentially, it simulates the shoulder Motor6Ds in the torso staying with the HumanoidRootPart rather than the torso, and rotating them relative to that. I wish to instead replicate this with a default R6 rig.

I’ve been trying to accomplish this on & off for the past few days and each time, I keep going until I burn out and can’t make sense of it anymore. I think what I have so far could be some kind of step in the right direction, but I’m too checked out to really tell. CFrames overwhelm me easily.

RuS:BindToRenderStep("AimConnection", 1, function()
	local aX, aY, _ = CFrame.new(head.Position, GetMouseHit().Position):ToEulerAnglesYXZ() --get mouse aim rotation
	local _, tY, _ = torso.CFrame:ToEulerAnglesYXZ() --torso Y rotation
	local _, rY, _ = rootPart.CFrame:ToEulerAnglesYXZ() --rootpart Y rotation
	local torsoWorldC0 = torso.CFrame:ToWorldSpace(torso["Right Shoulder"].C0) --get shoulder C0 in world cframe
	local worldC0 = rootPart.CFrame:ToWorldSpace(torso["Right Shoulder"].C0) --get shoulder C0 relative to rootpart instead of torso in world cframe
	local aimWorldC0 = worldC0 * CFrame.Angles(0, 0, aX) --apply aim relative to rootpart
	local aimTorsoWorldC0 = CFrame.new(torsoWorldC0.Position) * CFrame.Angles(aimWorldC0:ToEulerAnglesYXZ()) --idk
						
	game.Workspace.Test.WorldCFrame = aimWorldC0 --attachment for testing
	game.Workspace.Test1.WorldCFrame = aimTorsoWorldC0 --attachment for testing
	torso["Right Shoulder"].C0 = CFrame.new(torso["Right Shoulder"].C0.Position) * CFrame.Angles(0, math.rad(90),  aX) --apply to motor6d
	rootPart.CFrame = rootPart.CFrame:Lerp(CFrame.new(rootPart.Position) * CFrame.Angles(0, aY, 0), 0.1) --turn character
end)

I’ve tried looking at many forum posts but none of them are really what I’m looking for. They’re either EXACTLY the same query I’m having with no helpful answers, or CFrame questions that are almost what I’m looking for. However, if there is a post out there that perfectly answers my question, then please post it, as I may have somehow missed or misunderstood it. Thanks in advance.

Since it seems like you’re playing an animation on the character while also modifying the shoulder motors, you have to account for the offset of the torso from its rest position due to the animation. This offset is defined by rootPart.RootJoint.Transform, so to undo this offset you simply get its inverse before applying the same transformations you were doing:

torso["Right Shoulder"].C0 = rootPart.RootJoint.Transform:Inverse() * CFrame.new(torso["Right Shoulder"].C0.Position) * CFrame.Angles(0, math.rad(90),  aX)

Thank you for the response, however after another day of throwing myself at it I managed to figure it out.

The code looks like this:

--edited to be slightly more readable
local defaultRightShoulderC0 = rightShoulder.C0
RuS:BindToRenderStep("AimConnection", 1, function()
	local aX, aY, _ = CFrame.new(head.Position, GetMouseHit().Position):ToEulerAnglesYXZ() --get angles of head looking at mouse hit
	local rTorsoWorldC0 = torso.CFrame:ToWorldSpace(defaultRightShoulderC0) --get torso C0 (world space)
	local rRootPartWorldC0 = rootPart.CFrame:ToWorldSpace(defaultRightShoulderC0) --get rootpart C0 (world space)
	local rRootPartWorldAimC0 = rRootPartWorldC0 * CFrame.Angles(0, 0, -aX) --apply aim to rootpart C0 (world)
	local rRootTorsoOffset = rRootPartWorldC0:ToObjectSpace(rTorsoWorldC0) --get the offset between torso C0 (world) and root C0 (world)
	local rRootAimOffset = rRootPartWorldAimC0:ToWorldSpace(rRootTorsoOffset) --apply offset (local) to aimed rootpart C0 (world)
	local rTorsoAimOffset = rRootAimOffset:ToObjectSpace(rTorsoWorldC0) --get offset between aimed offset (world) and torso C0 (world)
	rightShoulder.C0 = defaultRightShoulderC0 * rTorsoAimOffset --apply on top of default C0 (local)
end)

Leaving this here for anybody who may come across this trying to accomplish what I’ve been trying to.

mark ur post as a solution

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.