Currently, my gun is scripted like this, and works fine.
-- SERVER SCRIPT local RepStorage = game:GetService("ReplicatedStorage") RepStorage.laser.OnServerEvent:connect(function(player,tool,ray,part,position,Damage,Color) local beam = Instance.new("Part", workspace) beam.Color = Color beam.FormFactor = "Custom" beam.Material = "Neon" beam.Transparency = 0.25 beam.Anchored = true beam.Locked = true beam.CanCollide = false local distance = (tool.Handle.CFrame.p - position).magnitude beam.Size = Vector3.new(0.3, 0.3, distance) beam.CFrame = CFrame.new(tool.Handle.CFrame.p, position) * CFrame.new(0, 0, -distance / 2) game:GetService("Debris"):AddItem(beam, 0.05) if part then local humanoid = part.Parent:FindFirstChild("Humanoid") if not humanoid then humanoid = part.Parent.Parent:FindFirstChild("Humanoid") end if humanoid then humanoid:TakeDamage(Damage) end end end)
-- LOCAL SCRIPT --//:Services: local RepStorage = game:GetService("ReplicatedStorage") local InputService = game:GetService("UserInputService") --//:Variables: local tool = script.Parent local player = game:GetService("Players").LocalPlayer --//:GunConfig: local GunConfig = tool.GunConfig local Ammo = GunConfig.Ammo.Value local Clips = GunConfig.Clips.Value local CoolDown = GunConfig.CoolDown.Value local Damage = GunConfig.Damage.Value local MaxAmmo = GunConfig.MaxAmmo.Value local Range = GunConfig.Range.Value local Color = GunConfig.LaserColor.Value local ReloadTime = GunConfig.ReloadTime.Value local KeyCodes = {Enum.KeyCode.R} --//:Debounces: local CanFire = GunConfig.CanFire.Value local Reloading = false local Firing = false --//:Main: local Update = function(bool) --Update AmmoUI if bool == true then player.PlayerGui.AmmoUI.Frame.CurrentAmmo.Text = (Ammo.."/"..MaxAmmo) elseif bool == false then player.PlayerGui.AmmoUI.Frame.CurrentAmmo.Text = " " end end local Reload = function() --Reload (duh) if Reloading == false then Reloading = true CanFire = false Ammo = 0 Update(true) wait(ReloadTime) Ammo = MaxAmmo Update(true) Reloading = false end end tool.Equipped:connect(function(mouse) --Equipped Update(true) InputService.InputBegan:connect(function(input,chatting) if input.KeyCode == KeyCodes[1] and not chatting then Reload() end end) mouse.Button1Down:connect(function() --FIRE!!!!!! (Semi) if CanFire == true and Ammo > 0 and player.Character.Humanoid.Health > 0 then CanFire = false Firing = true local ray = Ray.new(tool.Handle.CFrame.p, (mouse.Hit.p - tool.Handle.CFrame.p).unit * Range) local part, position = workspace:FindPartOnRay(ray, player.Character, false, true) RepStorage.laser:FireServer(tool,ray,part,position,Damage,Color) Ammo = Ammo - 1 Update(true) wait(CoolDown) CanFire = true Firing = false elseif CanFire == true and Ammo == 0 and player.Character.Humanoid.Health > 0 then --Reloads if ammo is 0 and idiot tries to fire gun Reload() end end) end) tool.Unequipped:connect(function() --Sets AmmoUI's text to blank when tool is unequipped Update(false) end)
Problem is, that it has perfect accuracy. I want to make it so it has spread, so if you shoot someone at point blank, you have a 100% chance of hitting them, and as the distance between you and the person increases, the accuracy decreases. Also, this is filtering enabled.
Also, I want the accuracy to have a variable that will control how accurate it is.
Use math.random. Say, per 10 studs, the math.random() had an extra range. So for every 10 studs, increase x in: math.random(0, x). If you wanted the max distance for the bullet to be to the torso or another part to be 5 studs, you could do math.random(0, x * 2), where x has a max of 5. * 2 because its not just 2 directions which the bullet could go in. It could go North, East, South, or West from your target. NOTE: You would need math.random() twice, one per Opposite direction. Then apply the cframe etc, I don't know that kind of stuff, but you could probably understand. That would provide accuracy based on distance. If you wanted the accuracy to be set at a certain spot along the circumfrence of the range, then you could just do math.random() to fire along certain intervals. NOTE: getting 5 from math.random() would be the center.
EDIT: A variable to control accuracy could be to lower the range of math.random().