I’m making a shotgun system, though I’m not good with raycasting and haven’t touched coding in a while, problem is I don’t know how to make a “secure” and optimized system. I can’t find a good way to keep it from being exploited (with something like an autoclicker) that isn’t crude
I’ll just paste the entire scripts so everything stupid you find please help lol
–client
local SingleShot = script.Parent
local Model = SingleShot:WaitForChild("SingleShot")
local Configuration = SingleShot:WaitForChild("Configuration")
local Events = SingleShot:WaitForChild("Events")
local Player = game.Players.LocalPlayer
local Mouse = Player:GetMouse()
local Character = Player.Character or Player.CharacterAdded:Wait()
local Animator = Character:WaitForChild("Humanoid"):WaitForChild("Animator")
local GunParams = RaycastParams.new()
GunParams.IgnoreWater = true
GunParams.FilterDescendantsInstances = {Character}
GunParams.CollisionGroup = "Raycast"
local DebrisLife = 10
local Debounce = false
local Reloading = false
local Cooldown = SingleShot:WaitForChild("Cooldown")
local function loadAnimation(animator,id)
local Anim = Instance.new("Animation")
Anim.AnimationId = "rbxassetid://"..tostring(id)
local LoadedAnim = animator:LoadAnimation(Anim)
Anim:Destroy()
return LoadedAnim
end
local IdleAnimation = loadAnimation(Animator, 17163654858)
local FireAnimation = loadAnimation(Animator, 17163684520)
local ReloadAnimation = loadAnimation(Animator, 17164431482)
local LoadedAnimations = {IdleAnimation, FireAnimation, ReloadAnimation}
local function onEquip()
local EquipSound = Instance.new("Sound")
EquipSound.Parent = Model.PrimaryPart
EquipSound.Volume = 0.5
EquipSound.SoundId = "rbxassetid://7405483764"
EquipSound:Play()
game.Debris:AddItem(EquipSound, 0.755)
IdleAnimation:Play()
SingleShot.Enabled = true
task.wait(0.6)
if Debounce and SingleShot.Enabled == true and Reloading == false then
Reloading = true
ReloadAnimation:Play()
end
end
local function onUnequip()
local UnequipSound = Instance.new("Sound")
UnequipSound.Parent = Model.PrimaryPart
UnequipSound.Volume = 0.5
UnequipSound.SoundId = "rbxassetid://609342351"
UnequipSound:Play()
game.Debris:AddItem(UnequipSound, 0.503)
for _,Animation in pairs(Animator:GetPlayingAnimationTracks()) do
if table.find(LoadedAnimations, Animation) then
Animation:Stop()
end
end
SingleShot.Enabled = false
Reloading = false
end
local function castRay(originPos, endPos)
local Xoffset = math.random(-Configuration.Spread.Value*100,Configuration.Spread.Value*100)/100
local Yoffset = math.random(-Configuration.Spread.Value*100,Configuration.Spread.Value*100)/100
local Offset = CFrame.Angles(math.rad(Xoffset),math.rad(Yoffset),0)
local Direction = (CFrame.new(originPos,endPos)*Offset).LookVector.Unit * Configuration.Range.Value
local Raycast = workspace:Raycast(originPos, Direction, GunParams)
if Raycast then
Events.CastRay:FireServer(Raycast.Instance, Raycast.Position)
if Raycast.Instance.Parent:FindFirstChildWhichIsA("Humanoid") then return end
local BulletHole = Instance.new("Part")
BulletHole.Name = "Hole"
BulletHole.Parent = Raycast.Instance
BulletHole.Transparency = 1
local holesize = math.random(4,5)/10
BulletHole.Size = Vector3.new(holesize, holesize, 0.05)
BulletHole.Anchored = true
BulletHole.CanCollide = false
BulletHole.CanQuery = false
BulletHole.CanTouch = false
BulletHole.CastShadow = false
BulletHole.Massless = true
local Decal = Instance.new("Decal")
Decal.Parent = BulletHole
Decal.Texture = "rbxassetid://4784905666"
BulletHole.CFrame = CFrame.lookAt(Raycast.Position, Raycast.Position + Raycast.Normal)
game.Debris:AddItem(BulletHole,DebrisLife)
end
end
local function onActivate()
if Debounce == false and Reloading == false then
Debounce = true
Events.Fire:FireServer()
FireAnimation:Play()
for i = 1,Configuration.Pellets.Value do
castRay(Model.GripPoint.Position, Mouse.Hit.Position)
end
task.wait(0.5)
if SingleShot.Enabled == true and Reloading == false then
Reloading = true
ReloadAnimation:Play()
end
end
end
SingleShot.Equipped:Connect(onEquip)
SingleShot.Unequipped:Connect(onUnequip)
SingleShot.Activated:Connect(onActivate)
Cooldown.Changed:Connect(function()
if Cooldown.Value == false then
Debounce = false
end
end)
--Animation Sequence Events
ReloadAnimation:GetMarkerReachedSignal("Eject"):Connect(function()
local EjectSound = Instance.new("Sound")
EjectSound.Parent = Model.PrimaryPart
EjectSound.Volume = 0.5
EjectSound.SoundId = "rbxassetid://9117307583"
EjectSound:Play()
game.Debris:AddItem(EjectSound, 0.824)
if Model.Shell.Transparency ~= 1 then
local EjectedShell = Model.Shell:Clone()
EjectedShell.Parent = workspace
EjectedShell.CanCollide = true
EjectedShell.Weld:Destroy()
EjectedShell.Velocity = EjectedShell.CFrame.UpVector * -25
game.Debris:AddItem(EjectedShell,DebrisLife/2)
end
Model.Shell.Transparency = 1
end)
ReloadAnimation:GetMarkerReachedSignal("Insert"):Connect(function()
local InsertSound = Instance.new("Sound")
InsertSound.Parent = Model.PrimaryPart
InsertSound.Volume = 0.5
InsertSound.SoundId = "rbxassetid://142429556"
InsertSound:Play()
game.Debris:AddItem(InsertSound, 0.339)
Model.Shell.Transparency = 0
end)
ReloadAnimation.Stopped:Connect(function()
if SingleShot.Enabled == true then
Reloading = false
Events.Reload:FireServer()
end
end)
–Server
local Model = SingleShot:WaitForChild("SingleShot")
local Configuration = SingleShot:WaitForChild("Configuration")
local Cooldown = SingleShot:WaitForChild("Cooldown")
local Events = SingleShot:WaitForChild("Events")
Events.CastRay.OnServerEvent:Connect(function(Player, Hit, Pos)
local Humanoid = Hit.Parent:FindFirstChild("Humanoid")
local Victim = game:GetService("Players"):GetPlayerFromCharacter(Hit.Parent)
if Humanoid then
if Victim == nil or Victim.Team ~= Player.Team then
Humanoid:TakeDamage(Configuration.Damage.Value)
if Hit.Name == "Head" then
Humanoid:TakeDamage(Configuration.Damage.Value)
end
end
end
--Digging noise
local ta = Instance.new("Attachment")
ta.Name = "soundpos"
ta.Position = Pos
ta.Parent = workspace.Terrain
local Sound = Instance.new("Sound")
Sound.RollOffMinDistance = 15
Sound.Name = "Hit"
Sound.SoundId = 'rbxassetid://'..1489924400
Sound.Parent = ta
Sound:Play()
game.Debris:AddItem(ta,0.5)
end)
Events.Fire.OnServerEvent:Connect(function()
Cooldown.Value = true
Model.GripPoint.Fire:Play()
end)
Events.Reload.OnServerEvent:Connect(function()
Cooldown.Value = false
end)
SingleShot.Equipped:Wait()
local Motor6D = Instance.new("Motor6D")
Motor6D.Parent = SingleShot
Motor6D.Name = "BodyAttach"
Motor6D.Part0 = SingleShot.Parent:WaitForChild("Torso")
Motor6D.Part1 = Model.GripPoint