Any alternative methods to achieving random gun spread?

I’m recreating Prison Life’s gun system (as a mini project) because I’m bored. However this issue has been bugging me for a while. How would I go about fixing it?

Someone provided me a formula for random gun spread, but it looks very weird, some bullets look merged together or look like one bullet and I have no idea how to fix this. I want the bullets to be spread individually.

Raycasting code:

function castRay(pos, origin)
	local raycastParams = RaycastParams.new()
	raycastParams.FilterDescendantsInstances = character:GetDescendants()
	raycastParams.FilterType = Enum.RaycastFilterType.Exclude

	local direction = (pos - origin).Unit
	local length = (origin - direction).Magnitude
	direction = (direction + Random.new():NextUnitVector() * fireSpread * math.random()).Unit * range

	local result = workspace:Raycast(origin, direction, raycastParams)
	local intersection = result and result.Position or origin + direction * range
	local distance
	if result then
		distance = math.clamp((origin - intersection).Magnitude, 0, range)
	else
		distance = math.clamp((pos - origin).Magnitude, 0, range)
	end

	local bullet = Instance.new("Part")
	bullet.Transparency = .3
	bullet.BrickColor   = BrickColor.new("Bright yellow")
	bullet.CanCollide   = false
	bullet.Anchored     = true
	bullet.CFrame       = CFrame.new(origin, intersection) * CFrame.new(0, 0, -distance / 2)
	bullet.Size         = Vector3.new(0.1, 0.1, distance)
	bullet.Name         = plr.Name.."'s".." Bullet"
	bullet.Parent       = workspace
	bullet.Material     = Enum.Material.Neon

	Debris:AddItem(bullet, 0.03)

	if result then
		remoteFolder:WaitForChild("castRay"):FireServer(origin, intersection, distance, result.Instance, damage)
	else
		remoteFolder:WaitForChild("castRay"):FireServer(origin, intersection, distance, nil, damage)
	end
end

BTW the spread is set to 0.1 because anything above that looks really weird

2 Likes

i would suggest making the angle which the bullets can fire ‘snap’ to a grid. if a bullet tries to merge with another bullet, choose a different spot on that grid.


each intersection represents a point where a bullet can go.
and intersections are chosen at random

1 Like

Hello,

Here’s the updated script for the shotgun to shoot bullets individually:

function castRay(pos, origin)
	local raycastParams = RaycastParams.new()
	raycastParams.FilterDescendantsInstances = character:GetDescendants()
	raycastParams.FilterType = Enum.RaycastFilterType.Exclude

	local numBullets = 5 -- Adjust the number of bullets as per your preference
	local bulletSpread = 2 -- Adjust the bullet spread value as per your preference

	for i = 1, numBullets do
		local direction = (pos - origin).Unit
		local length = (origin - direction).Magnitude
		local spreadVector = Vector3.new(math.random(), math.random(), math.random()) * bulletSpread
		direction = (direction + spreadVector).Unit * range

		local result = workspace:Raycast(origin, direction, raycastParams)
		local intersection = result and result.Position or origin + direction * range
		local distance
		if result then
			distance = math.clamp((origin - intersection).Magnitude, 0, range)
		else
			distance = math.clamp((pos - origin).Magnitude, 0, range)
		end

		local bullet = Instance.new("Part")
		bullet.Transparency = .3
		bullet.BrickColor   = BrickColor.new("Bright yellow")
		bullet.CanCollide   = false
		bullet.Anchored     = true
		bullet.CFrame       = CFrame.new(origin, intersection) * CFrame.new(0, 0, -distance / 2)
		bullet.Size         = Vector3.new(0.1, 0.1, distance)
		bullet.Name         = plr.Name.."'s".." Bullet"
		bullet.Parent       = workspace
		bullet.Material     = Enum.Material.Neon

		Debris:AddItem(bullet, 0.03)

		if result then
			remoteFolder:WaitForChild("castRay"):FireServer(origin, intersection, distance, result.Instance, damage)
		else
			remoteFolder:WaitForChild("castRay"):FireServer(origin, intersection, distance, nil, damage)
		end
	end
end

What i modified is i added a loop to generate multiple bullets (controlled by the numBullets variable). Each bullet has a random spread applied to its direction vector, ensuring that they spread individually. The spread amount is controlled by the bulletSpread variable.

Feel free to adjust the numBullets and bulletSpread values to achieve the desired spread effect for your shotgun.

I’ve never really delved too deep into the math side of Lua. Can you guide me through this? I am looking for and trying other solutions as we speak. thanks!

you dont need math to do what i suggested