Heya There!!
I’m working on a modular framework and I’m wondering how I would make automatic guns fire by holding down Mouse1. How the system works is that whenever a player equips a tool (which is a gear, not a model), a module script gets the tools settings which is a module script inside of the tool.
Of course, the settings will include stuff like ammo, damage, and if its automatic or not. How would I go by detecting to see if the tool is automatic?
InputController (LocalScript)
--[[SERVICES]]--
local Players = game:GetService("Players")
local ContextActionService = game:GetService("ContextActionService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
--[[FOLDERS]]--
local ClientModules = ReplicatedStorage:WaitForChild("ClientModules")
local RemoteEvents = ReplicatedStorage:WaitForChild("RemoteEvents")
local Weaponry = ReplicatedStorage:WaitForChild("Weaponry")
--[[MODULES]]--
local BaseGun = require(ReplicatedStorage.ClientModules.BaseGun)
--[[VARIABLES]]--
local Player = Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local PlayerMouse = Player:GetMouse()
--[[CONTROLS]]--
Character.ChildAdded:Connect(function(Child)
if Child:IsA("Tool") then
BaseGun:Equip(Child)
--//Functions
local function Fire(actionName, inputState, inputObject)
BaseGun:Fire(Character, Child:WaitForChild("Base"), PlayerMouse.Hit.Position)
end
--//Bind
ContextActionService:BindAction("Fire",Fire,false,Enum.UserInputType.MouseButton1)
end
end)
BaseGun (ModuleScript)
--[[SERVICES]]--
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Debris = game:GetService("Debris")
--[[FOLDERS]]--
local RemoteEvents = ReplicatedStorage:WaitForChild("RemoteEvents")
--[[MODULE]]--
local BaseGunModule = {}
BaseGunModule.__index = BaseGunModule
function BaseGunModule:Equip(Weapon)
self.Settings = require(Weapon:WaitForChild("Settings"))
--//Extra variables
self.LastFire = 0
self.AmmoRemember = self.Settings.AmmoHold
end
function BaseGunModule:Fire(Wielder, A, B)
--//Firerate/Debounce
local Now = os.clock()
if Now - self.LastFire < self.Settings.Firerate then warn("On cooldown. Stop.") return end
self.LastFire = Now
--//Checking to see if the gun has enough ammo
if self.Settings.AmmoHold >= 1 then
--//Firing the gun
self.Settings.AmmoHold -= 1
local RaycastParam = RaycastParams.new()
RaycastParam.FilterDescendantsInstances = {Wielder}
RaycastParam.FilterType = Enum.RaycastFilterType.Exclude
local Raycast = workspace:Raycast(A.Position, (B - A.Position).Unit * 5000, RaycastParam)
local RaycastInstance = Raycast.Instance
if RaycastInstance then
--//Humanoid check & damage
local Humanoid = RaycastInstance.Parent:FindFirstChildWhichIsA("Humanoid")
if not Humanoid then
--//The raycast didn't hit a humanoid.
return
end
if Humanoid and Humanoid.Health >= 1 then
Humanoid:TakeDamage(self.Settings.BaseDamage)
RemoteEvents.Fire:FireServer(Humanoid, self.Settings.BaseDamage)
end
--//Raycasting
self:Trace(A.Position, RaycastInstance.Position, B)
else
--//Raycasting if we didn't hit anything or hit a part.
local EndPoint = A + (B - A.Position).Unit * 5000
self:Trace(A, EndPoint)
end
else
self:Reload()
end
end
function BaseGunModule:Reload()
--//Reloading the gun if we have enough ammo.
if self.Settings.AmmoContain >= 1 then
self.Settings.AmmoHold = self.AmmoRemember
self.Settings.AmmoContain -= self.Settings.AmmoHold
else
warn("Find a refill station. You do not have any ammo remaining.")
end
end
--//Tracing
function BaseGunModule:Trace(A, B, C)
local Tracer = Instance.new("Part",workspace.Debris)
local Distance = (A - B).Magnitude
--//Customizing
Tracer.Anchored = true
Tracer.CanQuery = false
Tracer.Material = Enum.Material.Neon
Tracer.BrickColor = BrickColor.Yellow()
Tracer.Size = Vector3.new(0.1, 0.1, Distance)
Tracer.Transparency = 0.8
Tracer.CastShadow = false
--//Positioning
Tracer.CFrame = CFrame.lookAt(A, C) * CFrame.new(0, 0, -Distance/2)
Debris:AddItem(Tracer,0.05)
end
return BaseGunModule