Shotgun Spread Not Working

So basically, I’m trying to make the shotgun spread, by using an old post for help, but no success. No errors either. It just shoots one ray

-- ss in tool
local debris = game:GetService("Debris")
game.ReplicatedStorage.ShotgunFire.OnServerEvent:Connect(function(player, Character, HEADSHOT, BODY_DAMAGE, SHOOTY_PART, MousePos, HandleOfGun, Part_1, Part_2, Part_3, GunCon)
	local raycastParams = RaycastParams.new()
	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
	raycastParams.FilterDescendantsInstances = {Character, SHOOTY_PART, HandleOfGun, Part_1, Part_2, Part_3}
	local ray = workspace:Raycast(Part_1.Position, (MousePos - Part_1.Position).Unit * 100, raycastParams)
    local startPos	= Character:WaitForChild('Head').CFrame.p
	
	local spreadInterval = (SHOOTY_PART.Position - MousePos).magnitude
	local Min, Max = -(GunCon.Gun.Value/100) * spreadInterval, (GunCon.Gun.Value/100) * spreadInterval
	local shotgunBullet = Vector3.new((MousePos.X)+(math.random(Min, Max)), (MousePos.Y)+(math.random(Min, Max)), (MousePos.Z)+(math.random(Min, Max)))
	
    local ray = workspace:Raycast(SHOOTY_PART.Position, (MousePos - SHOOTY_PART.Position).Unit * 100, raycastParams)	
	        local direction = (MousePos - SHOOTY_PART.Position).Unit * 100
			local midPoint = SHOOTY_PART.Position + direction/2				
			local part = Instance.new("Part")
			part.Size = Vector3.new(0.2, 0.2,direction.Magnitude)
			part.CFrame = CFrame.new(midPoint, SHOOTY_PART.Position)
			part.Anchored = true
			part.CanCollide = false
			part.Parent = workspace
			part.BrickColor = BrickColor.new("New Yeller")
    		debris:AddItem(part,0.1)
if ray then
		local part = ray.Instance
		print(part)
		local humanoid = part.Parent:FindFirstChild("Humanoid")
		print("HumanoidFound")
		
		if part.Name == "Head" then
			humanoid.Health = humanoid.Health - math.random(20,40)
		else
			humanoid.Health = humanoid.Health - math.random(10,15)
		end
	end
end)

Have a great day y’all!

The old posts: Shotgun spread problem ,How do I make a raycast shotgun? - #7 by H_mzah

3 Likes
local Min, Max = -(GunCon.Gun.Value/100) * spreadInterval, (GunCon.Gun.Value/100) * spreadInterval

The values are IntValues, can someone please help?

1 Like

i believe this is what your looking for:

Well, I kinda want to understand how it works so I don’t have to ask this question multiple times, could you explain how it works? Thanks for taking your time to post

ok, so in loleris’ post, what he is essentially doing is firstly:

  1. Creating a CFrame 100 studs forward from the gun’s barrel

  2. Rotating it so that it is pointed sideways by a Random amount, (why he does math.pi * 2 * math.random(): he is just getting 360 degrees in radians, then multiplying that by a random number in between 0 and 1 to get a random amount of rotation between 0 and 360)

  3. multiplying its cframe times a cframe that is a few random studs to the side, to make the bullet actually move from the exact cframe it was hit in TOWARDS the rotation it was just given.

That should be it!

This what my code looks like:

local debris = game:GetService("Debris")
game.ReplicatedStorage.ShotgunFire.OnServerEvent:Connect(function(player, Character, HEADSHOT, BODY_DAMAGE, SHOOTY_PART, MousePos, HandleOfGun, Part_1, Part_2, Part_3)
	local raycastParams = RaycastParams.new()
	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
	raycastParams.FilterDescendantsInstances = {Character, SHOOTY_PART, HandleOfGun, Part_1, Part_2, Part_3}
    local startPos	= Character:WaitForChild('Head').CFrame.p
	
   local cf = CFrame.new(Character.Head.Position, MousePos)
   local function RandomSpreadAt100Studs(cf, spread_diameter)
   local target_cf = cf * CFrame.new(0, 0, -100) -- Get a CFrame 100 studs ahead
      * CFrame.Angles(0, 0, math.pi * 2 * math.random()) -- Turn CFrame randomly on  the Z axis
      * CFrame.new(0, math.random() * spread_diameter / 2, 0) -- Pick a random spread distance from the origin ray
      return CFrame.new(cf.Position, target_cf.Position)
   end
    local ray = workspace:Raycast(SHOOTY_PART.Position, (MousePos - SHOOTY_PART.Position).Unit * 100, raycastParams)	
	        local direction = (MousePos - SHOOTY_PART.Position).Unit * 100
			local midPoint = SHOOTY_PART.Position + direction/2				
			local part = Instance.new("Part")
			part.Size = Vector3.new(0.2, 0.2,direction.Magnitude)
			part.CFrame = CFrame.new(midPoint, SHOOTY_PART.Position)
			part.Anchored = true
			part.CanCollide = false
			part.Parent = workspace
			part.BrickColor = BrickColor.new("New Yeller")
    		debris:AddItem(part,0.1)
if ray then
		local part = ray.Instance
		print(part)
		local humanoid = part.Parent:FindFirstChild("Humanoid")
		print("HumanoidFound")
		if part.Name == "Head" then
			humanoid.Health = humanoid.Health - math.random(20,40)
		else
			humanoid.Health = humanoid.Health - math.random(10,15)
		end
	end
end)

I know there’s something wrong, I just don’t know what it is…

you never used the spread function:
try this:

local debris = game:GetService("Debris")
game.ReplicatedStorage.ShotgunFire.OnServerEvent:Connect(function(player, Character, HEADSHOT, BODY_DAMAGE, SHOOTY_PART, MousePos, HandleOfGun, Part_1, Part_2, Part_3)
	local raycastParams = RaycastParams.new()
	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
	raycastParams.FilterDescendantsInstances = {Character, SHOOTY_PART, HandleOfGun, Part_1, Part_2, Part_3}
    local startPos	= Character:WaitForChild('Head').CFrame.p
	
   local function RandomSpread(cf, spread_diameter)
      local target_cf = cf * CFrame.new(0, 0, -100) -- Get a CFrame 100 studs ahead
      * CFrame.Angles(0, 0, math.pi * 2 * math.random()) -- Turn CFrame randomly on  the Z axis
      * CFrame.new(0, math.random() * spread_diameter / 2, 0) -- Pick a random spread distance from the origin ray
      return target_cf.p
   end
local bulletpos = RandomSpread(SHOOTY_PART.CFrame, 10)
    local ray = workspace:Raycast(SHOOTY_PART.Position, (bulletpos - SHOOTY_PART.Position).Unit * 100, raycastParams)	
	        local direction = (bulletpos - SHOOTY_PART.Position).Unit * 100
			local midPoint = SHOOTY_PART.Position + direction/2				
			local part = Instance.new("Part")
			part.Size = Vector3.new(0.2, 0.2,direction.Magnitude)
			part.CFrame = CFrame.new(midPoint, SHOOTY_PART.Position)
			part.Anchored = true
			part.CanCollide = false
			part.Parent = workspace
			part.BrickColor = BrickColor.new("New Yeller")
    		debris:AddItem(part,0.1)
if ray then
		local part = ray.Instance
		print(part)
		local humanoid = part.Parent:FindFirstChild("Humanoid")
		print("HumanoidFound")
		if part.Name == "Head" then
			humanoid.Health = humanoid.Health - math.random(20,40)
		else
			humanoid.Health = humanoid.Health - math.random(10,15)
		end
	end
end)

There is a warning: Argument Count Mismatch

oops, its fixed now

3030300300030300

Nothing really change aside from the ray doesn’t go to where the mouse is

instead of writing the entire script, the method i always use when doing shooting calculations is this:

function sphericalMaxDistPos(maxRange)
     return camera.Focus.p + (mouse.Hit.p - camera.Focus.p).Unit * maxRange
end

local pos = mouse.Target and (mouse.Hit.p - camera.Focus.p).Magnitude <= maxGunRange and mouse.Hit.p or sphericalMaxDistPos(maxGunRange)

local rayparams = RaycastParams.new()
rayparams.FilterType = Enum.RaycastFilterType.Blacklist
rayparams.FilterDescendantsInstances = {localCharacter}

local ray = workspace:Raycast(camera.Focus.p, (camera.Focus.p - pos).Unit * maxGunRange, rayparams)
if ray and ray.Instance then
     print("Part found!")
end

Do I delete the whole script, or just delete some of it to to put this in?

just modify it so this code fits in it.

What is ‘camera’ the players camera?

yep
the variable is this:

local camera = workspace.CurrentCamera

For some reason ‘Mouse.Target’ is not working

local maxGunRange = 100
local camera = workspace.CurrentCamera
local debris = game:GetService("Debris")
game.ReplicatedStorage.ShotgunFire.OnServerEvent:Connect(function(player, Character, HEADSHOT, BODY_DAMAGE, SHOOTY_PART, MousePos, HandleOfGun, Part_1, Part_2, Part_3, mouse)
	local raycastParams = RaycastParams.new()
	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
	raycastParams.FilterDescendantsInstances = {Character, SHOOTY_PART, HandleOfGun, Part_1, Part_2, Part_3}
	local function sphericalMaxDistPos(maxRange)
     return camera.Focus.p + (mouse.Hit.p - camera.Focus.p).Unit * maxRange
    end

local pos = mouse.Target and (mouse.Hit.p - camera.Focus.p).Magnitude <= maxGunRange and mouse.Hit.p or sphericalMaxDistPos(maxGunRange)

local ray = workspace:Raycast(camera.Focus.p, (camera.Focus.p - pos).Unit * maxGunRange, raycastParams)
if ray and ray.Instance then
     print("Part found!")
end
	
   local function RandomSpread(cf, spread_diameter)
      local target_cf = cf * CFrame.new(0, 0, -100) -- Get a CFrame 100 studs ahead
      * CFrame.Angles(0, 0, math.pi * 2 * math.random()) -- Turn CFrame randomly on  the Z axis
      * CFrame.new(0, math.random() * spread_diameter / 2, 0) -- Pick a random spread distance from the origin ray
      return target_cf.p
   end
local bulletpos = RandomSpread(SHOOTY_PART.CFrame, 10)
	        local direction = (bulletpos - SHOOTY_PART.Position).Unit * 100
			local midPoint = SHOOTY_PART.Position + direction/2				
			local part = Instance.new("Part")
			part.Size = Vector3.new(0.2, 0.2,direction.Magnitude)
			part.CFrame = CFrame.new(midPoint, SHOOTY_PART.Position)
			part.Anchored = true
			part.CanCollide = false
			part.Parent = workspace
			part.BrickColor = BrickColor.new("New Yeller")
    		debris:AddItem(part,0.1)
if ray then
		local part = ray.Instance
		print(part)
		local humanoid = part.Parent:FindFirstChild("Humanoid")
		print("HumanoidFound")
		if part.Name == "Head" then
			humanoid.Health = humanoid.Health - math.random(20,40)
		else
			humanoid.Health = humanoid.Health - math.random(10,15)
		end
	end
end)

what do you mean its not working?

There is an error when I play the game 14:47:17.230 - Workspace.Shotgun.Script:12: attempt to index nil with ‘Target’, I don’t know what wrong

I deleted this:

if ray and ray.Instance then
     print("Part found!")
end

But still no sucess

Updated script

local maxGunRange = 100
local camera = workspace.CurrentCamera
local debris = game:GetService("Debris")
game.ReplicatedStorage.ShotgunFire.OnServerEvent:Connect(function(player, Character, HEADSHOT, BODY_DAMAGE, SHOOTY_PART, MousePos, HandleOfGun, Part_1, Part_2, Part_3, mouse)
	local raycastParams = RaycastParams.new()
	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
	raycastParams.FilterDescendantsInstances = {Character, SHOOTY_PART, HandleOfGun, Part_1, Part_2, Part_3}
	local function sphericalMaxDistPos(maxRange)
     return camera.Focus.Position + (mouse.Hit.Position - camera.Focus.Position).Unit * maxRange
    end

local pos = mouse.Target and (mouse.Hit.Position - camera.Focus.Position).Magnitude <= maxGunRange and mouse.Hit.Position or sphericalMaxDistPos(maxGunRange)

local ray = workspace:Raycast(camera.Focus.Position, (camera.Focus.Position - pos).Unit * maxGunRange, raycastParams)
   local function RandomSpread(cf, spread_diameter)
      local target_cf = cf * CFrame.new(0, 0, -100) -- Get a CFrame 100 studs ahead
      * CFrame.Angles(0, 0, math.pi * 2 * math.random()) -- Turn CFrame randomly on  the Z axis
      * CFrame.new(0, math.random() * spread_diameter / 2, 0) -- Pick a random spread distance from the origin ray
      return target_cf.Position
   end
local bulletpos = RandomSpread(SHOOTY_PART.CFrame, 10)
	        local direction = (bulletpos - SHOOTY_PART.Position).Unit * 100
			local midPoint = SHOOTY_PART.Position + direction/2				
			local part = Instance.new("Part")
			part.Size = Vector3.new(0.2, 0.2,direction.Magnitude)
			part.CFrame = CFrame.new(midPoint, SHOOTY_PART.Position)
			part.Anchored = true
			part.CanCollide = false
			part.Parent = workspace
			part.BrickColor = BrickColor.new("New Yeller")
    		debris:AddItem(part,0.1)
if ray then
		local part = ray.Instance
		print(part)
		local humanoid = part.Parent:FindFirstChild("Humanoid")
		print("HumanoidFound")
		if part.Name == "Head" then
			humanoid.Health = humanoid.Health - math.random(20,40)
		else
			humanoid.Health = humanoid.Health - math.random(10,15)
		end
	end
end)