How to make vector based recoil that isn't affected by mouse hit position distance?

I am working on my own vector based recoil that works similarly to CSGO’s recoil. I have this so far and it works pretty good but the issue I’m having is when I pull my mouse down into the ground to control my spray, the vector values are affected heavily by the mouse’s position causing the bullets to go much further in the direction than intended. How could I get around this?

Gun Module

local cu = .2
local cr = .2
local vecpattern = {
	{1, 0, 0, cu, cr },
	{2, 0, 0, cu, cr },
	{3, 1, 0, cu, cr },
	{4, 3, 0, cu, cr },
	{5, 6, 1, cu, cr },
	{6, 6, 2, cu, cr },
	{7, 8, 3, cu, cr },
	{8, 9, 4, cu, cr },
	{9, 10, 5, cu, cr },
	{10, 10, 5, cu, cr },
	{11, 11, 5, cu, cr },
	{12, 11, 3, cu, cr },
	{13, 11, 2, cu, cr },
	{14, 11, 1, cu, cr },
	{15, 10, 0, cu, cr },
	{16, 9, 0, cu, cr },
	{17, 8, 1, cu, cr },
	{18, 8, 2, cu, cr },
	{19, 9, 4, cu, cr },
	{25, 11, 0, cu, cr },
}
Recoil.vector = function(targetPos, u, r, start)
	local player = game:GetService("Players").LocalPlayer
	local mult = .5
	
	local newz = (-r*mult) + targetPos.Z
	local newy = (u*mult) + targetPos.Y
	local newx = (r*mult) + targetPos.X
	print(newy)
	local new = Vector3.new(newx, newy, newz)
	
	return new
end


Recoil.VecRecoil = function(targetPos, targetStart, Camera) 
	curshot = (tick() - lastclick >= recoil_reset and 1 or curshots + 1)
	lastclick = tick()
	local new
	for i, v in pairs(vecpattern) do
		if curshot <= v[1] then	
			local upAmount = v[2]
			local rightAmount = v[3]
			local camUp = .1 * v[4]
			local camRight = .1 * v[5]
			new = Recoil.vector(targetPos, upAmount, rightAmount, targetStart) --vector recoil
			Recoil.custom(Camera, camUp, camRight) --camera recoil
			print("v" .. " " .. v[1])
			break
		end
	end
	--print(new)
	return new
end

GunClient:

local targetPosition --Accuracy handling
local mousePosition = mouse.Hit.Position
targetPosition = mousePosition + Vector3.new((math.random(-Accuracy.X, Accuracy.X) * 0.01), (math.random(-Accuracy.Y, Accuracy.Y) * 0.01), (math.random(-Accuracy.Z, Accuracy.Z) * 0.01))

Example:
rblxhelp.wmv (7.3 MB)

I’m leaning towards just using ScreenPointToRay and just casting another ray with params beforehand.

@Quasiduck has explained this problem here through the diagram drawn in that post which is the method you are using with adding a vector, although the solution is for a different problem.

To solve the problem, keeping your method you will need to standardized the distance represented by the green vector in the above diagram. Assuming you have a ray origin or shoot part.

local direction = (mouse.Hit.p - ShootPart.CFrame.p).Unit
local modifiedMousePosition = ShootPart.CFrame.p+direction *100 --This will standardize and keep the distance the same 100 units away feel free to change 100.
targetPosition = modifiedMousePosition + Vector3.new((math.random(-Accuracy.X, Accuracy.X) * 0.01), (math.random(-Accuracy.Y, Accuracy.Y) * 0.01), (math.random(-Accuracy.Z, Accuracy.Z) * 0.01))
1 Like

You should randomise between adding the constructed Vector3 value and subtracting it.

1 Like