Viewmodel arms not positioned properly based off avatar

I’ve been struggling with this problem for about a year and it’s where viewmodels are positioned improperly based off of avatar type
Due to the nature of the gun system that it is used for, i will not tolerate solutions that boil down to making a viewmodel a seperate object, or a generic viewmodel.
I’m trying to make a viewmodel that is just positioned properly on all avatar types.
This is what it is supposed to look like



This is what it looks like on other avatars

And when i aim down sights before the aim attachment of the weapon is in a certain position, the weapon isn’t positioned properly and this occurs when i ads while the draw animation is still playing, or if i ads too quickly after ending it

local HideArms = false
local ArmNames = {"Arm", "Hand"}

-- camera spring, use that to adjust the recoil
--local SpringDamp = 1

local PlayersService = game:GetService("Players")
local RunService = game:GetService("RunService")

local function Lerp(a,b,t)
	return a*(1-t)+b*t
end

local h=Instance.new("Hint")
local function printh(...:string|number)
	h.Text=table.concat({...}," ")
	h.Parent=workspace
end

local module = {}
module.__index = module

function module.new()
	local Viewmodel = setmetatable({}, module)

	Viewmodel.Active = false

	return Viewmodel
end

--local DefaultFOV = 70

function module:Create(Gun:Tool, GunRootPart:BasePart, AimAtt:Attachment, ScopeAtt:Attachment, FirstAimOffset:CFrame, ScopeOffset:Vector3, ...)
	-- To use the ... in the Create function
	 --[[local Args = {
			{
				nil, -- Motor Object
				Name", -- String that should match the name of the Motor Object
				CFrame -- CFrame to set the Motors C0 to every frame
			}
		}]]
	-- ... = {Motor, Name, CF}, Make ... into a table

	self.Active = true
	local Args = {...}
	local Modules = Gun:WaitForChild("Modules")
	local Remotes = Gun:WaitForChild("Remotes")
	local Events = Gun:WaitForChild("Events")
	local GunRoot:Motor6D

	local Spring = require(Modules:WaitForChild("Spring"))
	local OnFire = Remotes:WaitForChild("OnRecoilRequest")
	local RecoilEvent = Events.Recoil
	local OnDraw = Events:WaitForChild("Draw")
	local OnAim = Events:WaitForChild("Aim")
	
	local Camera = workspace.CurrentCamera
	local Player = PlayersService.LocalPlayer
	local Character = Player.Character or Player.CharacterAdded:Wait()

	local Humanoid:Humanoid = Character:WaitForChild("Humanoid")
	--local CrouchingValue = Character:WaitForChild("Crouching")
	local LowerTorso, UpperTorso, Head
	local Root, Waist, Neck
	local HRP
	local Mag
	local SecondMag

	local Connections:{RBXScriptConnection} = {}

	local CameraSpring = Spring.spring.new(Vector3.zero)
	CameraSpring.s = 30
	CameraSpring.d = 1
	
	local StabilizeSpring = Spring.spring.new(Vector3.zero)
	StabilizeSpring.s = 30
	StabilizeSpring.d = 1
	
	local Alternation = 0
	local AimOffset = CFrame.new(0, 0, 0)
	local CameraOffset = Vector3.zero
	local AimValue = 0

	local LerpedAimOffset = AimOffset
	local LerpedAimValue = AimValue
	local Aimed = false
	
	if Humanoid.RigType == Enum.HumanoidRigType.R15 then
		LowerTorso = Character:WaitForChild("LowerTorso")
		UpperTorso = Character:WaitForChild("UpperTorso")
		Head = Character:WaitForChild("Head")
		HRP = Character:WaitForChild("HumanoidRootPart")
		Root = LowerTorso:WaitForChild("Root")
		Waist = UpperTorso:WaitForChild("Waist")
		Neck = Head:WaitForChild("Neck")
	elseif Humanoid.RigType == Enum.HumanoidRigType.R6 then
		LowerTorso = Character:WaitForChild("HumanoidRootPart")
		HRP = LowerTorso
		Root = LowerTorso:WaitForChild("RootJoint")
	end

	local function FindStringByTable(tbl:{string}, str:string)
		for index, pattern in pairs(tbl) do
			if string.find(str, pattern) then
				return true
			end
		end

		return false
	end

	local function GetArms()
		local Arms = {}

		for index, part in pairs(Character:GetChildren()) do
			if part:IsA("BasePart") and FindStringByTable(ArmNames, part.Name) then
				table.insert(Arms, part)
			end
		end

		return Arms
	end

	local Arms = GetArms()

	local function SetArmsVisible()
		for index, arm in pairs(Arms) do
			arm.LocalTransparencyModifier = 0
		end
	end

	local function Recoil(strength:number, horizontalstrength:number, Stability:number, StabilizeRate:number)
		if Alternation == 0 then
			Alternation = 1
		else
			Alternation = 0
		end
		StabilizeSpring.s = StabilizeRate or 30
		Stability = Stability or 1
		horizontalstrength = horizontalstrength or 0
		horizontalstrength = Alternation == 1 and horizontalstrength or -horizontalstrength
		CameraSpring:Accelerate(Vector3.new(strength*0.02, horizontalstrength*0.02, 0))
		--if Stabilizes then
			task.delay(0.05, function()
				CameraSpring:Accelerate(Vector3.new(-(strength * math.clamp(Stability, 0, 1))*0.02, -(horizontalstrength *math.clamp(Stability, 0, 1))*0.02, 0))
			end)
		--end
	end

	local DefaultRootC0 = Root.C0
	local DefaultRootC1 = Root.C1
	local DefaultWaistC0 = Waist.C0
	local DefaultWaistC1 = Waist.C1
	local DefaultNeckC0 = Neck.C0
	local DefaultNeckC1 = Neck.C1

	local HasDoneResetting = true

	function self:Reset()
		if Humanoid.RigType == Enum.HumanoidRigType.R15 then
			Root.C0 = DefaultRootC0
			Root.C1 = DefaultRootC1
		elseif Humanoid.RigType == Enum.HumanoidRigType.R6 then
			Root.C0 = CFrame.Angles(math.rad(90), math.rad(180), 0)
		end
	end

	local function Update(dt)
		local CamCF = Camera.CFrame
		local CamFocus = Camera.Focus

		local CamCFPosition = CamCF.Position
		local CamFocusPosition = CamFocus.Position
		local FocusDirection = CamFocusPosition - CamCFPosition
		local FocusUnit = FocusDirection.Unit
		local FocusMagnitude = FocusDirection.Magnitude

		local CamRotation = CamCF.Rotation
		local CamRX, CamRY, CamRZ = CamRotation:ToOrientation()

		local IsInFirstPerson = math.floor(FocusMagnitude) <= 0

		Camera.CFrame = CamCF:ToWorldSpace(CFrame.Angles(CameraSpring.p.X, CameraSpring.p.Y, CameraSpring.p.Z))

		if IsInFirstPerson then
			if not HideArms then
				SetArmsVisible()
			end
			if AimAtt then
				local CameraCF = Camera.CFrame
			end
			-- according to camera modules, r15 head y offset = 1.5
			--local HeadOffset = CFrame.new((DefaultRootC1:Inverse()*DefaultWaistC0*DefaultWaistC1:Inverse()*DefaultNeckC0*DefaultNeckC1:Inverse()).Position)
			--printh(HeadOffset.X,HeadOffset.Y, HeadOffset.Z)
			HasDoneResetting = false
			--LerpedAimOffset = LerpedAimOffset:Lerp(AimOffset, AimValue > 1/2 and 0.2 or 0.4)
			Root.C1 = DefaultRootC1
			LerpedAimOffset = LerpedAimOffset:Lerp(Aimed and Camera.CFrame:ToObjectSpace(AimAtt.WorldCFrame) or CFrame.identity, AimValue > 1/2 and 0.2 or 0.4)
			LerpedAimValue = Lerp(LerpedAimValue,AimValue,0.1)
			if Humanoid.RigType == Enum.HumanoidRigType.R15 then
				-- should have done this to fix it. huzzah
				Root.C0 = CFrame.new(0,-1,0)
				:ToWorldSpace(CFrame.new(0,2.5,0))
				:ToWorldSpace(CFrame.Angles(CamRX, 0, 0))
				:ToWorldSpace(CFrame.new(0,2.5,0):Inverse())
			
				Root.C1 = DefaultRootC1
				:ToWorldSpace(CFrame.new(LerpedAimOffset.p))

				for _, Object in pairs(Args) do
					if Object[1] ~= nil then
						Object[1].C0 = Object[3](CamRX, LerpedAimOffset)
					end
				end
				
				Humanoid.CameraOffset = LerpedAimValue >= 0.9 and CameraOffset or Vector3.zero
			elseif Humanoid.RigType == Enum.HumanoidRigType.R6 then
				Root.C0 = CFrame.Angles(math.rad(90), math.rad(180), 0)
				:ToWorldSpace(CFrame.new(0, 0, 1.5))
				:ToWorldSpace(CFrame.Angles(CamRX, 0, 0):Inverse())
				:ToWorldSpace(CFrame.new(0, 0, 1.5):Inverse())
			end
		else
			if not HasDoneResetting then
				self:Reset()
			end
			HasDoneResetting = true
		end
		if not self.Active then
			RunService:UnbindFromRenderStep("UpdateViewmodel_"..Gun.Name)
			self:Reset()
			for Index, Connection in pairs(Connections) do
				Connection:Disconnect()
			end
		end
	end

	local function GetGunAttachment(child:Instance)
		if child:IsA("Motor6D") then
			for i, v in pairs(Args) do
				task.spawn(function()
					if child.Name == Args[i][2] then 
						Args[i][1] = child
						repeat
							child.AncestryChanged:Wait()
						until child.Parent ~= HRP
					end
					if Args[i][1] == child then
						Args[i][1] = nil
					end
				end)
			end
		end
	end
	if AimAtt ~= nil then
		local function ADSPositionCamNew(Aiming)
			local RootToCameraOffset = Vector3.new(0, 2.5, 0)
			local AimPositionCF = AimAtt.WorldCFrame
			Aimed = Aiming
			--AimOffset = Aimed and --[[(FirstAimOffset ~= nil and FirstAimOffset or]] Camera.CFrame:ToObjectSpace(AimPositionCF) or CFrame.new(0,0,0)

			--AimOffset = Aiming and --[[(FirstAimOffset ~= nil and FirstAimOffset or]] CameraCF:ToObjectSpace(AimPositionCF) or CFrame.new(0,0,0)
			if not FirstAimOffset and Aiming then
				warn("It is recommended to copy this and paste to variable FirstAimOffset: CFrame.new("..tostring(AimOffset)..")")
			end
			if ScopeAtt ~= nil then
				AimValue = Aiming and 1 or 0
				CameraOffset = Aiming and (ScopeOffset ~= nil and ScopeOffset) or Vector3.zero
				if not ScopeOffset and Aiming then
					task.delay(1, function()
						--warn("It is recommended to copy this and paste to variable ScopeOffset: Vector3.new("..tostring(CameraCF:ToObjectSpace(ScopeAtt.WorldCFrame).Position)..")")
					end)
				end
			end
		end
		table.insert(Connections, OnAim.Event:Connect(ADSPositionCamNew))
		end
		--local function ADSPositionCam(Aiming)
		--	local CameraCF = Camera.CFrame
		--	local AimPositionCF = AimAtt.WorldCFrame
		--	AimOffset = Aiming and --[[(FirstAimOffset ~= nil and FirstAimOffset or]] CameraCF:ToObjectSpace(AimPositionCF) or CFrame.new(0,0,0)
		--	if not FirstAimOffset and Aiming then
		--		warn("It is recommended to copy this and paste to variable FirstAimOffset: CFrame.new("..tostring(AimOffset)..")")
		--	end
		--	if ScopeAtt ~= nil then
		--		AimValue = Aiming and 1 or 0
		--		CameraOffset = Aiming and (ScopeOffset ~= nil and ScopeOffset) or Vector3.zero
		--		if not ScopeOffset and Aiming then
		--			task.delay(1, function()
		--				warn("It is recommended to copy this and paste to variable ScopeOffset: Vector3.new("..tostring(CameraCF:ToObjectSpace(ScopeAtt.WorldCFrame).Position)..")")
		--			end)
		--		end
		--	end
		--end
		--table.insert(Connections, OnAim.Event:Connect(ADSPositionCam))
	

	RunService:BindToRenderStep("UpdateViewmodel_"..Gun.Name, Enum.RenderPriority.Character.Value, Update)
	table.insert(Connections, OnFire.OnClientEvent:Connect(Recoil))
	table.insert(Connections, RecoilEvent.Event:Connect(Recoil))
	table.insert(Connections, HRP.ChildAdded:Connect(GetGunAttachment))
	
end

function module:Destroy()
	self.Active = false
	self:Reset()
end

return module

This code moves rotates the lowertorso of the player, making what resembles a viewmodel.
image
the function was based on this. the camera should set itself on point A when you ads but the problem is that the distance between A and C is not equal to that of other characters