Gun spread being wacky

Hey, its me again…

Basically Im trying to make a gun (basically my first time) and I’m trying reallly hard to get the spread to work.
In this gif the spread works whenever I aim it at a non exist object, but not when I hit a part, as well as it doesnt really work, it stays at a very… small spread which isnt ideal…
https://gyazo.com/1c72727bccb92de975c720532301cf97

Heres my script: (currently local, converting once I figure this thing out)

local player = game:GetService("Players").LocalPlayer
 
local mouse = player:GetMouse()

local isFiring = false

local damage = 3
local headshotMultiplier = 1.75
local function buttonDwn()
	isFiring = true
	while isFiring == true do
		wait(.08)
		print("Mouse pressed!")
		local ray = Ray.new(player.Character.Head.CFrame.p, (mouse.Hit.p - player.Character.Head.CFrame.p * Vector3.new(math.random(1,5),math.random(1,5),math.random(1,5))).unit * 300)
		local part, position = workspace:FindPartOnRay(ray, player.Character, false, true)
 
		local beam = Instance.new("Part", workspace)
		beam.BrickColor = BrickColor.new("Bright red")
		beam.FormFactor = "Custom"
		beam.Material = "Neon"
		beam.Transparency = 0.25
		beam.Anchored = true
		beam.Locked = true
		beam.CanCollide = false
 
		local distance = (player.Character.Head.CFrame.p - position).magnitude
		beam.Size = Vector3.new(0.3, 0.3, distance)
		beam.CFrame = CFrame.new(player.Character.Head.CFrame.p, position) * CFrame.new(0, 0, -distance / 2)
 
		game:GetService("Debris"):AddItem(beam, 0.05)
 
		if part then
			print(part.Name)
			local humanoid = part.Parent:FindFirstChild("Humanoid")
 
			if not humanoid then
				humanoid = part.Parent.Parent:FindFirstChild("Humanoid")
			end
 			if part.Name == 'Head' and humanoid then
				humanoid:TakeDamage(damage * headshotMultiplier)
			end
			if humanoid then
				humanoid:TakeDamage(damage)
			end
			if part.Name == 'Handle' and part.Parent:IsA('Hat') or part.Parent:IsA('Accessory') and humanoid then
				humanoid:TakeDamage(damage * headshotMultiplier)
			end
		end
	end
end

mouse.Button1Down:Connect(function()
	buttonDwn()
end)
mouse.Button1Up:Connect(function()
	isFiring = false
end)

Thanks!

2 Likes

You need to multiply the random offset by the distance the bullet is traveling.

local offset = Vector3.new(
   math.random(-5,5),
   math.random(-5,5),
   math.random(-5,5)
) *distance / 1000 --you can use this to control the accuracy - smaller div = less accuracy. 


4 Likes

Where would I place this code so everything works accordingly? Position and Distance are placed (oddly)?

This is having a hard time as the ray needs to be positioned, not the visible part:

local part, position = workspace:FindPartOnRay(ray, player.Character, false, true)
local distance = (player.Character.Head.CFrame.p - position).magnitude

local endPos = mouse.Hit.p
local startPos = player.Character.Head.CFrame.p

local CF = CFrame.new(startPos,endPos)*CFrame.Angles(math.rad(math.random(-15,15)),math.rad(math.random(-15,15)),0)

local DirVec = CF.LookVector

Then you can just cast a ray using DirVec for the direction component (arg2)

2 Likes

Alright, I’ll try this when I go on my computer, thanks! :slight_smile:

Works tremendously! Thank you!