Help with bullet spread

So I’ve been using FastCast for my guns, and I wanted to implement bullet accuracy to make it look a bit more natural.

This is my code:

function bulletSpread(maxAngle, direction)
	--maxAngle is a number, direction is a vector
	--Get random angles for both axis first
	local yAngle = math.random(-maxAngle * 10, maxAngle * 10) / 10
	local xAngle = math.random(-maxAngle * 10, maxAngle * 10) / 10
	
	--my Current solution: get the offset from the baseCframe, and then apply it to the calculated vector
	local unitVector = direction.Unit
	local baseCframe = CFrame.new(0, 0, 1) --Ew
	local dirCframe = CFrame.new(direction)
	local offsetCframe = baseCframe:Inverse() * dirCframe
	
	--Now use trigonometry to convert into new vector
	--Im using Cframe (0,0,1) becoz im gonna change it on x and y axis, so its kinda intuitive to leave the z untouched
	--it wont remain a unit vector after this, but that has no effect so i dont care
	local y = math.tan(math.rad(yAngle))
	local x = math.tan(math.rad(xAngle))
	
	local adjustedCframe = CFrame.new(x, y, 1)
	local finalCFrame = adjustedCframe * offsetCframe
	local newVector = finalCFrame.Position
	
	return newVector
end

(I’m calculating the offset from a base Cframe, because the player can fire in any direction and my brains are unable to directly apply the spread to the provided vector)

This works, but I’m not happy with having to do this, because I feel like there is a way to apply the spread directly. I will much appreciate any help in doing this, thank you.

1 Like

Why not just create a CFrame with yAngle and xAngle. They just multiply the direction by that CFrame to rotate it.
Something like this:

local yAngle = math.random(-maxAngle * 10, maxAngle * 10) / 10
local xAngle = math.random(-maxAngle * 10, maxAngle * 10) / 10
	
local rotationCFrame = CFrame.Angles(xAngle,yAngle, 0)
	
return rotationCFrame * direction