Hello. I look for an efficient way of making a shotgun spread. I made a shotgun for a commission that I work on, but the spread looks unrealistic AT ALL:
https://streamable.com/7hgd5r
Here is the code that I use:
while wait(info.Rate) do
if isShooting and not script.Parent.Configuration.IsOnSafe.Value and not script.Parent.Configuration.IsReloading.Value and script.Parent.Ammo.Value ~= 0 then
local damage = 0;
local humanoid = nil;
function create_Bullet()
local rayCastParams = RaycastParams.new();
local wl = {workspace.Baseplate, workspace:FindFirstChild("NPC")}
for _, v in ipairs(game.Players:GetChildren()) do
if v ~= game.Players.LocalPlayer then
table.insert(wl, #wl + 1, v.Character)
end
end
rayCastParams.FilterDescendantsInstances = wl
rayCastParams.FilterType = Enum.RaycastFilterType.Whitelist
local bulletClone = script.Bullet:Clone();
bulletClone.Parent = workspace
bulletClone.CFrame = CFrame.new(script.Parent.ShootPart.Position, mouse.Hit.p.Unit * info.Range)
bulletClone.Transparency = 0
wait(.03)
local sPosition = bulletClone.Position;
local bodyVelocity = Instance.new("BodyVelocity");
local x = math.random(-info.Spread, info.Spread)
local y = math.random(-info.Spread, info.Spread)
local z = 0
local rayUnit = ((mouse.Hit.p + Vector3.new(x, y / 2, z)) - bulletClone.Position).Unit * 250
bodyVelocity.Velocity = rayUnit
local corout = coroutine.create(function()
local startPos = bulletClone.Position;
repeat wait() until (bulletClone.Position - sPosition).Magnitude < (mouse.Hit.p.Unit * info.Range - bulletClone.Position).Magnitude
bulletClone:Destroy()
end)
coroutine.resume(corout)
bulletClone.Anchored = false
bodyVelocity.Parent = bulletClone
local result = workspace:Raycast(bulletClone.Position, ((mouse.Hit.p.Unit * info.Range + Vector3.new(x, y / 2, z)) - sPosition).Unit * info.Range, rayCastParams);
if result and result.Instance then
if result.Instance.Parent:FindFirstChildOfClass("Humanoid") or result.Instance.Parent.Parent:FindFirstChildOfClass("Humanoid") then
damage = damage + info.Damage;
humanoid = result.Instance.Parent:FindFirstChildOfClass("Humanoid") or result.Instance.Parent.Parent:FindFirstChildOfClass("Humanoid")
end
end
end
local bulletsCreated = 1;
local c = coroutine.create(function()
repeat game:GetService("RunService").Stepped:Wait()
bulletsCreated = bulletsCreated + 1
create_Bullet()
until bulletsCreated >= info.BulletsInOneShot
if damage > 0 then
if humanoid ~= nil then
if info.TeamKill then
damageRemoteEvent:FireServer(humanoid, damage)
else
if game.Players:GetPlayerFromCharacter(humanoid.Parent) then
if game.Players:GetPlayerFromCharacter(humanoid.Parent).Team ~= game.Players.LocalPlayer.Team then
damageRemoteEvent:FireServer(humanoid, damage)
else
end
else
damageRemoteEvent:FireServer(humanoid, damage)
end
end
end
end
end)
coroutine.resume(c)
elseif script.Parent.Ammo.Value == 0 and isShooting then
if not script.Parent.Configuration.IsReloading.Value and script.Parent.Ammo.Value ~= script.Parent.MaxAmmo.Value then
reloadRemote:FireServer()
game:GetService("Players").LocalPlayer:WaitForChild("PlayerGui"):WaitForChild("Weapon").Main.Disabled = true
game:GetService("Players").LocalPlayer:WaitForChild("PlayerGui"):WaitForChild("Weapon").WeaponName.Text = "Reloading..."
wait(2 / script.Parent.ReloadSpeed.Value + .5)
game:GetService("Players").LocalPlayer:WaitForChild("PlayerGui"):WaitForChild("Weapon").Main.Disabled = false
end
end
end