Raycasting Gun Spread

Hello!
I made a gun system by using raycasting.
But I am bad at math and don’t know how to make a spread

Can someone help, please?

Source
script.Parent.CastBullet.OnServerEvent:Connect(function(plr, mouse, dmg, FirePoint, char, range)
	local ray = Ray.new(FirePoint.WorldCFrame.Position, (mouse.Position - FirePoint.WorldCFrame.Position).Unit * range)
	
	local ignore = workspace.NoRay:GetChildren();
	table.insert(ignore, plr.Character)
	
	local part, position = game.Workspace:FindPartOnRayWithIgnoreList(ray, ignore)
	
	local bullet = Instance.new("Part", workspace.NoRay)
	bullet.Name = "Bullet"
	bullet.Anchored = true
	bullet.Material = Enum.Material.Neon
	bullet.CanCollide = false
	bullet.Locked = true
	bullet.BrickColor = BrickColor.new("New Yeller")
	
	local distance = (FirePoint.WorldCFrame.Position - position).Magnitude
	bullet.Size = Vector3.new(0.1, 0.1, distance)
	bullet.CFrame = CFrame.new(FirePoint.WorldCFrame.Position, position) * CFrame.new(0, 0, - distance / 2)
	
	if part then
		local hum = part.Parent:FindFirstChild("Humanoid")
		
		if not hum then
			hum = part.Parent.Parent:FindFirstChild("Humanoid")
		end
		
		if hum then
			hum:TakeDamage(dmg)
			if part.Name == "Head" then
				hum:TakeDamage(dmg * 2)
			end
		end
	end
	
	game.Debris:AddItem(bullet, 0.1)
end)
7 Likes

To add spread to a raycasting weapon, simply add a math.random() on the finishing position.

local SPREAD = 1000 -- set some value for it
local spreadPosition = Vector3.new(
    FirePoint.WorldCFrame.Position.X + math.random(-SPREAD, SPREAD)/1000,
    FirePoint.WorldCFrame.Position.Y + math.random(-SPREAD, SPREAD)/1000,
    FirePoint.WorldCFrame.Position.Z + math.random(-SPREAD, SPREAD)/1000
)

I reckon there was a better method.


Looks like parent argument of Instance.new() is here again. Do not use it.

6 Likes

What do i have to do with “spreadPosition”

Use that to replace the FirePoint.WorldCFrame.Position in the first line on the function:

local ray = Ray.new(FirePoint.WorldCFrame.Position, (mouse.Position - spreadPosition).Unit * range)
6 Likes

Works!!!
Thank you! :smile: :smile:

1 Like

This is a bad method for spread. Adjusting based on the mouse position will lead to inaccurate spread based on range. You need to alter a unit direction rather than the final position.

4 Likes

Already fixed it in the PMs with an alternative of creating a fixed cone-shaped spread through an alternative:

local accurateRay = Ray.new(FirePoint.WorldCFrame.Position, (mouse.Position - spreadPos).Unit * range)
local calculatedRay = Ray.new(accurateRay.Origin, CFrame.Angles(math.rad(math.random(-spreadAngle, spreadAngle)), math.rad(math.random(-spreadAngle, spreadAngle)), math.rad(math.random(-spreadAngle, spreadAngle))) * accurateRay.Direction)
4 Likes

mouse.Position - spreadPos

You shouldn’t be doing it like this. You need a lookVector.

How would I make the spread angle?