Keeping arms stationary regardless of torso animations

Basically, I want the arms to remain at the same rotation, regardless of the torso’s animations. The current issue is when the player moves, or idles, the animation knocks their gun off course, making their shot inaccurate.

Example:

What I instead want is the arms to not move alongside the torso at all and instead are stationary (similar to whats shown in this video, although I’ve just disabled the torso animations entirely.)

I know I need to somehow offset the arms C0 by the RootJoint’s transform, although I cannot figure out the math correctly.

any help would be greatly appreciated.

4 Likes

Recently I have discovered a wonderful thing: IKControl.
The wonder is: with its weight equal to 1 it overrides any animation.
It requires some math indeed.
How it works you can check here, sorry for bothering you with my experience (work in progress, but weapons do aim to mouse position): First Person Camera With Weapons [TEST PROJECT] - Roblox

1 Like

as cool as IK control (and cool project btw), I’ve never had it play very well with R6. And my primary issue isnt with getting the arms and torso to point in the correct direction, but the the Left and Right arm’s Motor6D’s being attached to the torso meaning it inherits its motio. I’m curious if its possible to keep the arm’s rotation stationary regardless of the RootJoints transform (which would be animation offset)

1 Like

For animations, you can use the .Transform property and apply it at RunService.PreSimulation. This will cancel out the torsos animation movement.

There are a few alternatives but I can’t say much without seeing your code.

1 Like

This isn’t what I wanted, I stated in the original post that I wanted the torso animations to remain, but for the left and right arm to essentially reverse the torso animation so it stays in place. I tried to multiply the left and right shoulder’s C0 by the inverse of the torso’s transform, and it doesnt seem to work. the way I intended, and instead I get this sort of a result.

The code in the green box is the important parts.

What im doing here is multiplying the torso’s transform, then the aiming offset, then the transform for the player leaning back and forth, and then the original shoulder C0’s, and then anything else which shouldn’t effect the prior calculations.

I never said this was meant to remove them completely…

Are you doing it within a RunService.PreSimulation connection or on a RenderStepped connection?

Provide us with the code so we can understand what you’re doing.

1 Like

I would prefer to keep the torso animations in its entirety since I can manually adjust the weight when needed. And to answer your question before its being ran on a RenderStepped. Switching to a PreSimulation connection does not change anything. The code from the image I sent is the main important parts to this, The limb’s motor6D’s C0 is set to the associated ReturnedValues index. E.g. Left Hip = ReturnedValues.LLeg

local function AddCF(dt)
	--local BaseLLegCF, BaseRLegCF = FootPlantingModule.Parallel(dt)
	local HeadRotation, TorsoLookRot, LLegLookRot, RLegLookRot, LArmLookRot, RArmLookRot, LArmVerticalCalc, RArmVerticalCalc = CalculateHeadMovement(PlayerStuff.Limbs, Character, dt)
	local LeaningCF, HeadLeaningCF = AnimateLeaningDir(dt, PlayerStuff.Limbs, PlayerStuff.Controller, nil)
	
	local CamCFOffset = TablesModule:AddCFrameDebuffToTable(CFrame.new(), ClientVariables.PlayerCFOffsets.Cam)
	local HeadCFOffset = TablesModule:AddCFrameDebuffToTable(CFrame.new(), ClientVariables.PlayerCFOffsets.Head)
	local TorsoCFOffset = TablesModule:AddCFrameDebuffToTable(CFrame.new(), ClientVariables.PlayerCFOffsets.Torso)
	local LArmCFOffset = TablesModule:AddCFrameDebuffToTable(CFrame.new(), ClientVariables.PlayerCFOffsets.LArm)
	local RArmCFOffset = TablesModule:AddCFrameDebuffToTable(CFrame.new(), ClientVariables.PlayerCFOffsets.RArm)
	local LLegCFOffset = TablesModule:AddCFrameDebuffToTable(CFrame.new(), ClientVariables.PlayerCFOffsets.LLeg)
	local RLegCFOffset = TablesModule:AddCFrameDebuffToTable(CFrame.new(), ClientVariables.PlayerCFOffsets.RLeg)

	local LTorsoTransform = (CFrame.new():Lerp(LeaningCF.Rotation, LArmAimingProgress))
	local RTorsoTransform = (CFrame.new():Lerp(LeaningCF.Rotation, RArmAimingProgress))
	local AnimationOffset = PlayerStuff.Motors.Torso.Transform:Inverse()

	if PlayerStuff.Character:GetAttribute("State") == "Ragdolled" then
		ClientVariables.ReturnedValues.Cam = ClientVariables.RootMotors.OriginalCamMotor
		ClientVariables.ReturnedValues.LArm = ClientVariables.RootMotors.OriginalLArmMotor
		ClientVariables.ReturnedValues.RArm = ClientVariables.RootMotors.OriginalRArmMotor
		ClientVariables.ReturnedValues.Head = ClientVariables.RootMotors.OriginalNeckMotor
		ClientVariables.ReturnedValues.Root = ClientVariables.RootMotors.OriginalRootMotor
		ClientVariables.ReturnedValues.LLeg = ClientVariables.RootMotors.OriginalLLegMotor
		ClientVariables.ReturnedValues.RLeg = ClientVariables.RootMotors.OriginalRLegMotor
	else
		ClientVariables.ReturnedValues.Cam = ClientVariables.RootMotors.OriginalCamMotor * CamCFOffset
		
		ClientVariables.ReturnedValues.LArm = LArmLookRot * LTorsoTransform * ClientVariables.RootMotors.OriginalLArmMotor * LArmVerticalCalc * LArmCFOffset
		ClientVariables.ReturnedValues.RArm = RArmLookRot * RTorsoTransform * ClientVariables.RootMotors.OriginalRArmMotor * RArmVerticalCalc * RArmCFOffset
		
		ClientVariables.ReturnedValues.Head = ClientVariables.RootMotors.OriginalNeckMotor * HeadCFOffset * HeadRotation * HeadLeaningCF
		ClientVariables.ReturnedValues.Root = ClientVariables.RootMotors.OriginalRootMotor * TorsoCFOffset * TorsoLookRot * LeaningCF
		ClientVariables.ReturnedValues.LLeg = LLegLookRot * ClientVariables.RootMotors.OriginalLLegMotor * LLegCFOffset
		ClientVariables.ReturnedValues.RLeg = RLegLookRot * ClientVariables.RootMotors.OriginalRLegMotor * RLegCFOffset
	end

	--ClientVariables.ReturnedValues.FootplantingLLeg = BaseLLegCF
	--ClientVariables.ReturnedValues.FootplantingRLeg = BaseRLegCF

end

How about remaking whole animation so that the direction of arms is kept without changing torso animation?

1 Like

Right that doesn’t help but I made a small code snippet that does what you asked.

local RunService = game:GetService("RunService")
local Character = script.Parent
local Torso = Character:WaitForChild("Torso")

local Camera = workspace.CurrentCamera

local Motor6Ds = {
	["LeftShoulder"] = Torso:FindFirstChild("Left Shoulder"),
	["RightShoulder"] = Torso:FindFirstChild("Right Shoulder"),
}

local Motor6DsOffset = {
	["LeftShoulder"] = Motor6Ds.LeftShoulder.C0,
	["RightShoulder"] = Motor6Ds.RightShoulder.C0,
}

RunService.RenderStepped:Connect(function()
	local TorsoToCamRot = Torso.CFrame:ToObjectSpace(CFrame.new(Torso.CFrame.Position)*Camera.CFrame.Rotation)
	Motor6Ds.RightShoulder.C0 = CFrame.new(Motor6DsOffset.RightShoulder.Position) * 
		TorsoToCamRot * Motor6DsOffset.RightShoulder.Rotation
	Motor6Ds.LeftShoulder.C0 = CFrame.new(Motor6DsOffset.LeftShoulder.Position) * 
		TorsoToCamRot * Motor6DsOffset.LeftShoulder.Rotation
end)

It moves the arm to the torso while rotating them based on the camera and prevents all torso animations from messing it up.

1 Like

The player probably won’t hold the gun at all times, so walking/running without any arm movement will look very horrible.
Also, it’s not the arm animations. The OP probably already overwrites the arm animations using animation priorties.

okay I’ve managed to fix the bug, the solution was embarrassingly easy

for the random person who has the same issue 4 years from now:

2 Likes

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