Object Animation Re-Rigging Script

Some animators may find it easiest to create weapon and tool animations relative to the HumanoidRootPart. This makes a lot of sense because the HumanoidRootPart stays put during an animation, offering a stable point for precise adjustments.

However, in many games, you actually need that weapon or tool to move with a specific body part, like the Right Arm. Simply re-attaching the weapon from the HumanoidRootPart to the Right Arm after it’s been animated will cause problems. The weapon will look completely out of place because its animation data is still trying to position it relative to the HumanoidRootPart, even though it’s now connected elsewhere.

Below is a script I’ve created that allows you to transfer the “attachment” to a different body part while maintaining the original animation as how it is displayed. To use this script, edit the key components commented below. Run the script in the command bar and a fixedAnimations model will have all the fixed animations saved in it.


local targetRig = workspace.SpearFix; -- select the rig here
local AnimSaves = targetRig.AnimSaves:GetChildren();
local model = Instance.new("Model");
model.Name = "fixedAnimations";
model.Parent = workspace;

local originalWeaponJoint = targetRig.MeshPart.OldJoint; -- edit here (normally the weapon in this case would be attached straight to the HumanoidRootPart having a C0 of 0,0,0). You need to name it OldJoint so that we can figure out where the weapon would be since the Motor6D represents the static offset between Part0 and Part1 and Pose data is transformed onto the Motor6D. Make sure you turn Enabled off for this joint.
local desiredWeaponJoint = targetRig.MeshPart.HandleJoint; -- This is your new joint that you want (typically will be RightArm, LeftArm etc as Part0). 

for i = 1, #AnimSaves do 
	local animSave = AnimSaves[i]:Clone();
	animSave.Parent = model;
	
	local keyFrames = animSave:GetChildren();
	for k = 1, #keyFrames do 
		local keyFrame = keyFrames[k];
		
		-- Get the poses
		local humanoidRootPartPose = keyFrame.HumanoidRootPart;
		local weaponPose = humanoidRootPartPose.MeshPart; -- change MeshPart to the KeyFrame name
		local torsoPose = humanoidRootPartPose.Torso;
		local rightArmPose = torsoPose["Right Arm"];
		local leftArmPose = torsoPose["Left Arm"];
		
		local humanoidRootPartWorldCFrame = humanoidRootPartPose.CFrame;
		local rootJoint = targetRig.HumanoidRootPart.RootJoint
		local torsoWorldCFrame = humanoidRootPartWorldCFrame * rootJoint.C0 * torsoPose.CFrame * rootJoint.C1:Inverse();
		local rightShoulderJoint = targetRig.Torso["Right Shoulder"];
		local leftShoulderJoint = targetRig.Torso["Left Shoulder"];
		local rightArmWorldCFrame = torsoWorldCFrame * rightShoulderJoint.C0 * rightArmPose.CFrame * rightShoulderJoint.C1:Inverse();
		local leftArmWorldCFrame = torsoWorldCFrame * leftShoulderJoint.C0 * leftArmPose.CFrame * leftShoulderJoint.C1:Inverse();
		local weaponWorldCFrame = humanoidRootPartPose.CFrame * originalWeaponJoint.C0 * weaponPose.CFrame * originalWeaponJoint.C1:Inverse();
		-- Below attaches it to the leftArm. If you want a different body part you can edit accordingly
		local newWoodPoseRelativeToLeftArm = desiredWeaponJoint.C0:Inverse() * leftArmWorldCFrame:Inverse() * weaponWorldCFrame * desiredWeaponJoint.C1; -- edit leftArmWorldCFrame to what you want
		
		weaponPose.Parent = leftArmPose; -- edit this parent to the pose of the part you want
		weaponPose.CFrame = newWoodPoseRelativeToLeftArm; -- edit this cframe
	end
end


Left Side is After, Right Side is Before. The animations would play fine it’s just that if you didn’t have a animation that accounted for the fact that the default rig is to the HumanoidRootPart it would look awkward. Let me know if you have any questions.

5 Likes

can you provide and example model or .rbxl, or testing place… I do not quite get why this is needed , if you use a plugin to reposition the handle, the animations seem to play fine…

Imagine you wanted to animate a sword being thrown in front of you. If you were to rig the sword to your right arm, it would create a scenario in which any form of “breathing” or movement would affect the overall position and orientation of the sword which may not be preferred. This is where animators may rig the weapon to the HumanoidRootPart as it doesn’t move in animation and serves as an origin. This method of animating is fine if you account for all possible animations in the game needing to hold the sword in an “idle” state. What happens if you don’t is that the sword will “reset” back to it’s original position if there is no keyframe for it to interpolate to (In case of rigging to the HumanoidRootPart, it would be inside the character which can look awkward). This is where the script can come in handy.

example.rbxl (83.2 KB)

I’ve provided an example where you would want the original rig to be on the right arm (you can see how it breaks the animation creating an offset because the original animation was created relative to the HumanoidRootPart). The script recalculates the offset and updates the keyframe to it’s relative to a body part while maintain the same CFrame.

R6HumanoidRootPart Is the dummy with the original animation
R6DesireWeld Is where we want the new “joint” to be without breaking the animation
R6Fixed is after copying the new save from fixedAnimations into the AnimSaves to see the result.

If you head into R6Fixed and open up the animator, you’ll notice now that the sword moves relative to the Right Arm where if you were to open the animator on the R6HumanoidRootPart, moving the Right Arm has no influence on the sword.

1 Like