Weapon sway makes weapon bobble

So basically I had a couple of people help me with the math of weapon sway. I dont understand a lot of the math myself but I do understand the basic ideas. Whenever the mouse is moved the weapon sways but bobbles up and down really quickly. This does not work for my game. There is a spring script in the local script which controls my weapon. Please help me understand how to get rid of this bobble. Or if there is a better way to do this, I need help understanding so a rewritten script would be appreciated. Also The local script is located in the tool. I am trying to achieve very little sway kind of like phantom forces, this is difficult for me.

Local Script piece attatching weapon:

local nine = 9
local thirty = 30	
local CamZRef = game.workspace.CurrentCamera
local pitchAngleRef = CamZRef.CFrame.LookVector.Y
local UpDoMovRef = CFrame.Angles(pitchAngleRef, 0, 0) * gunCfOffsetVal.Value * gunShotVal.Value * gunLoadVal.Value * CFrame.Angles(0, math.rad(90), 0)
game.ReplicatedStorage.HoldGun:FireServer(UpDoMovRef)
RunService.RenderStepped:Connect(function(dt)
	aimPosSpring:update(dt)
	aimRotSpring:update(dt)
	local CamZ = game.workspace.CurrentCamera
	local headCf = Head.CFrame
	local BodyAttCf = ToolBase.CFrame
	local camCf = CamZ.CFrame
	local camRotCf = camCf - camCf.Position
	local targBodyAttCf = camRotCf * gunCfOffsetVal.Value
	local headCfRot = charac.Head.CFrame - charac.Head.Position
	local xRot, yRot, zRot = (camCf * CFrame.Angles(0, math.rad(90), 0)):ToEulerAnglesYXZ()	
	aimPosSpring.Target = targBodyAttCf.Position
	aimRotSpring.Target = Vector3.new(xRot, yRot, zRot)
	local rotSpringPos = aimRotSpring.Position
	print(xRot, yRot, zRot)
	charac.Head.ToolGrip.C0 = headCfRot:Inverse() * CFrame.new(aimPosSpring.Position) * CFrame.Angles(0, math.atan2(camCf.LookVector.X, camCf.LookVector.Z) - math.rad(90), 0) * CFrame.Angles(rotSpringPos.X, 0, rotSpringPos.Z)
end)

Spring Module Script in Local Script:

-- Constants

local ITERATIONS	= 8

-- Module

local SPRING	= {}

-- Functions 

function SPRING.create(self, mass, force, damping, speed)

	local spring	= {
		Target		= Vector3.new();
		Position	= Vector3.new();
		Velocity	= Vector3.new();

		Mass		= mass or 5;
		Force		= force or 50;
		Damping		= damping or 4;
		Speed		= speed  or 4;
	}

	function spring.shove(self, force)
		local x, y, z	= force.X, force.Y, force.Z
		if x ~= x or x == math.huge or x == -math.huge then
			x	= 0
		end
		if y ~= y or y == math.huge or y == -math.huge then
			y	= 0
		end
		if z ~= z or z == math.huge or z == -math.huge then
			z	= 0
		end
		self.Velocity	= self.Velocity + Vector3.new(x, y, z)
	end

	function spring.update(self, dt)
		local scaledDeltaTime = math.min(dt,1) * self.Speed / ITERATIONS

		for i = 1, ITERATIONS do
			local iterationForce= self.Target - self.Position
			local acceleration	= (iterationForce * self.Force) / self.Mass

			acceleration		= acceleration - self.Velocity * self.Damping

			self.Velocity	= self.Velocity + acceleration * scaledDeltaTime
			self.Position	= self.Position + self.Velocity * scaledDeltaTime
		end

		return self.Position
	end

	return spring
end

-- Return

return SPRING

Before recommending any scripts I recommend that you understand what your springs are doing in the first place in order to debug the problem by yourself and so that you can make future adjustments to it and get results you want.

One method I always use to debug CFrame is to do piece by piece CFrame operations. Basically you isolate what happens in each CFrame operation individually:

First you start with one CFrame for example here:

charac.Head.ToolGrip.C0 = headCfRot:Inverse()

Then you will add another CFrame like the spring CFrame operation here by CFrame.new :

charac.Head.ToolGrip.C0 = headCfRot:Inverse() * CFrame.new(aimPosSpring.Position)```

Then the most important part is noticing the effects of adding this cframe. If this CFrame is working as intended like causing the viewmodel to bob then keep it. If not then you would only change this part.

But yeah that’s the debugging process. You will be able to understand CFrame multiplication this way and I can testify this :100: :fire: :100: :fire: :100: :fire: without even knowing the matrix math underlaying it.

Otherwise I recommend fully and don’t deviate from it following the fps tutorial which is where you got the spring module from I believe, then try to explain how the result was achieved with the given methods in your own words.

I appreciate it but I cannot learn this kind of math right now I am very busy. All I really want to work on is my game, I dont think there is anything wrong with not understanding a lot of the math that goes into games cause it’s pretty advanced for people like me. Anyway It did not work I was just hoping for a solution honestly.

1 Like