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.