Issue w/ 3rd Person Arms

off = CFrame.new(off.X * 0.8,off.Y * 0.7,off.Z * 0.6)

In this particular case it modifiies the current offset, which is either gunOffset or gunRest, in other cases it’s one of the two, however ADS triggers gunOffset to be used so in no case is the value modified when gunRest is being used instead.

I’ve created a script to test the function. Does everything in here look correct? Unfortunately it does not reproduce the bug. It may also be that the actual error doesn’t lay here in the ArmCFrame module, but possibly in the code used to animate between positions. How did you determine that the bug is in this code?

local ServerScriptService = game:GetService 'ServerStorage'
local ReplicatedStorage = game:GetService 'ReplicatedStorage'

local ArmCFrame = require(script.Parent.ArmCFrame)

local rootPartCFrame= {
	Male = CFrame.new(-35, 3.677, -75.485);
	Female = CFrame.new(-35, 3.689, -80.709);
}

local gender = 'Male'
local character = ReplicatedStorage.Rigs[gender]:Clone()
character.PrimaryPart = character.HumanoidRootPart
character:SetPrimaryPartCFrame(rootPartCFrame[gender])
character.Parent = workspace
local endPart = ServerScriptService.endPart:Clone()
endPart.Parent = workspace

local function setMotors(off, fire)
	if fire then
		off = CFrame.new(off.X * 0.8, off.Y * 0.7, off.Z * 0.6)
	end
	endPart.CFrame = off + character.Head.Position
	ArmCFrame.Righty(true, character, endPart, gender)
end

wait(5) -- so I can see what is going on

while true do
	-- Test entering resting
	print 'resting'
	setMotors(ArmCFrame.gunRest, false)
	wait(1)

	-- Test resting shot
	print 'resting fire'
	setMotors(ArmCFrame.gunRest, true)
	wait(1)

	-- Test going back to resting after a shot
	print 'resting'
	setMotors(ArmCFrame.gunRest, false)
	wait(1)

	-- Test transition to ADS while not shooting
	print 'ADS'
	setMotors(ArmCFrame.gunOffset, false)
	wait(1)

	-- Test ADS shot
	print 'ADS fire'
	setMotors(ArmCFrame.gunOffset, true)
	wait(1)

	-- Test going back to ADS after a shot
	print 'ADS'
	setMotors(ArmCFrame.gunOffset, false)
	wait(1)

	-- Test going back to resting while not shooting
	print 'resting'
	setMotors(ArmCFrame.gunRest, false)
	wait(1)

	-- Test going to ADS while shooting
	print 'resting fire'
	setMotors(ArmCFrame.gunRest, true)
	wait(1)
	print 'ADS'
	setMotors(ArmCFrame.gunOffset, false)
	wait(1)

	-- Test going to resting while shooting
	print 'ADS fire'
	setMotors(ArmCFrame.gunOffset, true)
	wait(1)

	print '\nRESTARTING\n'
end

Because the tweening/positioning of the main weld works fine, it’s the arms themselves that are having the issue.

Oh, and in the sprinting case, the bug only occurs with pistols, works fine when sprinting with any other gun, which the gun uses the rest offset

Maybe could I get you replace the Righty function with this function and give us the output when it works and when it doesn’t? I need to run off to class but will be back in 3 hours.

m.Righty = function(bool, char, endpart, gender)

    local upperTorso = char:FindFirstChild("UpperTorso")
    local upperC0 = game.ReplicatedStorage.Rigs[gender or "Male"].RightUpperArm.RightShoulder.C0
    local lowerC0 = game.ReplicatedStorage.Rigs[gender or "Male"].RightLowerArm.RightElbow.C0
    local shoulderMotor = char.RightUpperArm.RightShoulder
    local elbowMotor = char.RightLowerArm.RightElbow

print(([[Righty input: {
	reset: %s,
	endPart.Position: %s,
	gender: %s,
	upperC0: %s,
	lowerC0: %s,
}]]):format(
	tostring(bool), 
	tostring(endPart),
	tostring(gender),
	tostring(upperC0),
	tostring(lowerC0)
))

    if upperTorso then
        if bool then
            local shoulderCF = upperTorso.CFrame * upperC0
            local plane, shoulderAngle, elbowAngle = solveIK(shoulderCF, endpart.Position, a, b)

            shoulderMotor.C0 = upperTorso.CFrame:toObjectSpace(plane) * cfAngles(shoulderAngle, 0, 0)
            elbowMotor.C0 = lowerC0 * cfAngles(elbowAngle, 0, 0)
        else
            shoulderMotor.C0 = upperC0
            elbowMotor.C0 = lowerC0
        end
    end

print(([[Righty output: {
	shoulderMotor.C0: %s,
	elbowMotor.C0: %s,
}]]):format(
	tostring(shoulderMotor.C0),
	tostring(elbowMotor.C0)
))

end

I have this running on RenderStepped so this is gonna be a bit difficult to fetch, but I’ll try.

Edit:
Prints flew by so I hope I snagged the right ones (had to deliberately cause an error in the case where the arms are turned off)

Bug does not occur: https://i.gyazo.com/bf57ffb910cf31f3cd48d2249ad3d1a4.png
Bug does occur: https://i.gyazo.com/90cf922556cca4af205884c2b473e341.png

Okay, I’m back! And I have some bad news: I plugged in motor positions and neither set of outputs caused the issue we saw in the videos. Here are two pictures with the two different outputs hardcoded into the function (just ignore the input printed in the output window, it doesn’t matter since I hardcoded the motor values). That was a lot of typing large decimals!

Bad Motors:

Good Motors:

So here is where we are at. Either we got the wrong input/output set that caused the issue, or the issue doesn’t lay in this code. What I’d recommend doing is recording the input/output and have a script print it in a structured format so you could copy and paste it into another script which allows you to replay those values, pause, slow down, and replay. I’d keep it to a bare minimum, no tweening, just a simple R15 model, just a raw setting of motors and stepping through a set of data. Once you identify the troublesome input/output sets, it should be easy to dissect what part of the code is causing those strange values. On the other hand, if the bug doesn’t occur in the replay, then something else is causing the issue.

Hehe, once you find the troublesome input/output set, I’d be nice to have it in a copy/paste-able format! Sorry, this’ll probably take it bit… we are at the pinnacle of debugging here!

Write a couple of lines of code to detect the glitch, and spit out the data only then. Or bind a keyboard key to and event that will print out the values you need, and just punch the key when you see the problem, and when you don’t (for comparison).

In general, for debugging something like this, you should isolate the as little code as is needed to produce the problem, and publish it to a test place for forum members to look at, rather than pastebin snippets or screenshots. Strip out everything that is not required, or dead code, down to the simplest publishable repro case.

Was not home the past couple of days. Found the issue. Don’t wanna share because it hits hard in the self esteem. Thank you both for your help.