Out of pure boredom and curiosity, I decided to tackle the challenge of making a primary and secondary gun system. While it was working for a little while, I have arrived at the part of merging the local handler scripts together, and it no longer works. I was wondering if someone could attempt to fix the code, as it is very broken (the guns do not show up, the viewmodels are lower than usual and more). Below is the local handler:
local guns = game.ReplicatedStorage:WaitForChild("EquippedGuns")
local PistolModel = guns:WaitForChild("Pistol")
local RifleModel = guns:WaitForChild("FN Scar")
local ViewmodelContainer = Instance.new("Part")
ViewmodelContainer.Name = "ViewmodelContainer"
ViewmodelContainer.Anchored = true
ViewmodelContainer.CanCollide = false
ViewmodelContainer.Transparency = 1
ViewmodelContainer.Size = Vector3.new(0, 0, 0)
ViewmodelContainer.Parent = game.Workspace
local Viewmodel = game.ReplicatedStorage:WaitForChild("Viewmodel")
local AnimFolder = game.ReplicatedStorage:WaitForChild("PistolAnimations") -- Update the animation folder to the common folder if you want to share animations between guns
local mainModule = require(game.ReplicatedStorage.MainModule)
local SpringModule = require(game.ReplicatedStorage.SpringModule)
local IsPlayerHoldingMouse = false
local CanFire = true
local Delay = 0.1
local RecoilSpring = SpringModule.new()
local BobbleSpring = SpringModule.new()
local SwayingSpring = SpringModule.new()
local Fire = game.ReplicatedStorage:WaitForChild("Fire")
local ammoval = game.ReplicatedStorage:WaitForChild("Values"):WaitForChild("AmmoAmount")
ammoval.Value = 7
local PistolAmmoAmount = 7
local RifleAmmoAmount = 30
local EquippedGun = nil
Viewmodel.Parent = ViewmodelContainer
local function weldgun(gunModel)
local handle = gunModel:WaitForChild("GunComponents"):WaitForChild("Handle")
local weld = Instance.new("Weld")
weld.Name = "Weld"
weld.Part0 = handle
weld.Part1 = ViewmodelContainer
weld.C1 = handle.CFrame:ToObjectSpace(ViewmodelContainer.CFrame)
weld.Parent = handle
end
local function equipGun(gunModel)
if EquippedGun == gunModel then
-- Already equipped, unequip the gun
EquippedGun = nil
mainModule.unequip(Viewmodel, AnimFolder.Hold)
else
-- Equip the new gun
EquippedGun = gunModel
mainModule.equip(Viewmodel, gunModel, AnimFolder.Hold)
end
end
weldgun(PistolModel)
weldgun(RifleModel)
game:GetService("UserInputService").InputBegan:Connect(function(input)
if input.KeyCode == Enum.KeyCode.Q then
equipGun(PistolModel)
elseif input.KeyCode == Enum.KeyCode.E then
equipGun(RifleModel)
end
end)
game:GetService("RunService").RenderStepped:Connect(function(dt)
if EquippedGun == PistolModel then
mainModule.update(Viewmodel, dt, RecoilSpring, BobbleSpring, SwayingSpring, PistolModel)
elseif EquippedGun == RifleModel then
mainModule.update(Viewmodel, dt, RecoilSpring, BobbleSpring, SwayingSpring, RifleModel)
end
end)
game:GetService("UserInputService").InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
if CanFire and EquippedGun then
local AmmoAmount = 0
if EquippedGun == PistolModel then
AmmoAmount = PistolAmmoAmount
elseif EquippedGun == RifleModel then
AmmoAmount = RifleAmmoAmount
end
if AmmoAmount > 0 then
AmmoAmount -= 1
ammoval.Value -= 1
CanFire = false
RecoilSpring:shove(Vector3.new(5, 2, 3))
coroutine.wrap(function()
local FireSound = EquippedGun.GunComponents.Sounds.Fire:Clone()
FireSound.Parent = game.Workspace
FireSound.Parent = nil
FireSound:Destroy()
end)()
coroutine.wrap(function()
wait(0.2)
RecoilSpring:shove(Vector3.new(-2.8, math.random(-4, 4), -10))
end)()
local CastParams = RaycastParams.new()
CastParams.IgnoreWater = true
CastParams.FilterType = Enum.RaycastFilterType.Blacklist
CastParams.FilterDescendantsInstances = {Viewmodel, game.Players.LocalPlayer.Character}
local Mouse = mainModule.GetMouse(1000, CastParams)
mainModule.cast(EquippedGun.GunComponents.Barrel.Position, Mouse, 5, game.ReplicatedStorage.Damage)
Fire:FireServer(EquippedGun.GunComponents.Barrel.Position, Mouse)
wait(0.2)
CanFire = true
end
end
elseif input.UserInputType == Enum.UserInputType.MouseButton2 then
if EquippedGun then
mainModule.aim(true, Viewmodel, EquippedGun)
end
end
end)
game:GetService("UserInputService").InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton2 then
if EquippedGun then
mainModule.aim(false, Viewmodel, EquippedGun)
end
elseif input.KeyCode == Enum.KeyCode.R then
if EquippedGun == PistolModel then
print(game.Players.LocalPlayer.Name.." reloaded")
PistolAmmoAmount = mainModule.reload(Viewmodel, AnimFolder.Reload, 30)
elseif EquippedGun == RifleModel then
print(game.Players.LocalPlayer.Name.." reloaded")
RifleAmmoAmount = mainModule.reload(Viewmodel, AnimFolder.Reload, 30)
end
end
end)
Fire.OnClientEvent:Connect(function(client, origin, endposition)
if client ~= game.Players.LocalPlayer then
mainModule.cast(origin, endposition, 5, nil)
end
end)
And here is the module script:
local module = {}
local function GetBobbing(addition)
return math.sin(tick() * addition * 1.3) * 0.8
end
function module.update(viewmodel, dt, RecoilSpring, BobbleSpring, SwayingSpring, gun)
viewmodel.HumanoidRootPart.CFrame = game.Workspace.Camera.CFrame
local MouseDelta = game:GetService("UserInputService"):GetMouseDelta()
local Character = game.Players.LocalPlayer.Character or game.Players.LocalPlayer.CharacterAdded:Wait()
local UpdatedRecoilSpring = RecoilSpring:update(dt)
local UpdatedSwaySpring = SwayingSpring:update(dt)
gun.GunComponents.Sight.CFrame = gun.GunComponents.Sight.CFrame:Lerp(viewmodel.HumanoidRootPart.CFrame, game.ReplicatedStorage.Values.AimAlpha.Value)
viewmodel.HumanoidRootPart.CFrame *= CFrame.new(UpdatedSwaySpring.X, UpdatedSwaySpring.Y, 0)
viewmodel.HumanoidRootPart.CFrame *= CFrame.Angles(math.rad(UpdatedRecoilSpring.X) * 2, 0, 0)
game.Workspace.Camera.CFrame *= CFrame.Angles(math.rad(UpdatedRecoilSpring.X), math.rad(UpdatedRecoilSpring.Y), math.rad(UpdatedRecoilSpring.Z))
end
function module.weldgun(gun)
local Main = gun.GunComponents.Handle
for i, v in ipairs(gun:GetDescendants()) do
if v:IsA("BasePart") and v ~= Main then
local newMotor = Instance.new("Motor6D")
newMotor.Name = v.Name
newMotor.Part0 = Main
newMotor.Part1 = v
newMotor.C0 = newMotor.Part0.CFrame:inverse() * newMotor.Part1.CFrame
newMotor.Parent = Main
end
end
-- Set the PrimaryPart of the pistol model to the Handle
gun.PrimaryPart = Main
end
function module.equip(viewmodel, gun, hold)
local gunHandle = gun.GunComponents.Handle
local HRP_Motor6D = viewmodel:WaitForChild("HumanoidRootPart").Handle
gun.Parent = viewmodel
HRP_Motor6D.Part1 = gunHandle
local Hold = viewmodel.AnimationController:LoadAnimation(hold)
Hold:Play()
end
function module.cast(origin, endposition, velocity, damage)
local Bullet = Instance.new("Part")
Bullet.Name = "Bullet"
Bullet.Parent = workspace.Bullets
Bullet.Size = Vector3.new(1,1,3)
Bullet.Anchored = true
Bullet.CanCollide = false
Bullet.Color = Color3.new(0.933333, 0.803922, 0.0117647)
Bullet.Material = Enum.Material.Metal
Bullet.CFrame = CFrame.new(origin, endposition)
local Loop
Loop = game:GetService("RunService").RenderStepped:Connect(function(dt)
Bullet.CFrame *= CFrame.new(0, 0, -velocity * (dt * 60))
if (Bullet.Position - origin).magnitude > 5000 then
Bullet:Destroy()
Loop:Disconnect()
end
local HitPart, HitPoint, HitNormal = workspace:FindPartOnRay(Ray.new(Bullet.Position, Bullet.CFrame.LookVector * velocity * 1.5))
if HitPart then
if HitPart.Parent:FindFirstChild("Humanoid") and damage ~= nil then
game.ReplicatedStorage:WaitForChild("Damage"):FireServer(HitPart.Parent, damage)
print("bullet from " .. game.Players.LocalPlayer.Name .. " hit a player")
else
print("bullet hit a wall")
Loop:Disconnect()
Bullet:Destroy()
end
end
end)
end
function module.aim(toaim, viewmodel, gun)
if toaim then
game:GetService("TweenService"):Create(game.ReplicatedStorage.Values.AimAlpha, TweenInfo.new(0.5), {Value = 1}):Play()
else
game:GetService("TweenService"):Create(game.ReplicatedStorage.Values.AimAlpha, TweenInfo.new(0.5), {Value = 0}):Play()
end
end
function module.GetMouse(Distance, CastParams)
local MouseLocation = game:GetService("UserInputService"):GetMouseLocation()
local UnitRay = game:GetService("Workspace").Camera:ViewportPointToRay(MouseLocation.X, MouseLocation.Y)
local origin = UnitRay.Origin
local endp = UnitRay.Direction * Distance
local Hit = game:GetService("Workspace"):Raycast(origin, endp, CastParams)
if Hit then
return Hit.Position
else
return UnitRay.Origin + UnitRay.Direction * Distance
end
end
function module.reload(viewmodel, reloadAnim, ammoamt)
print("module recieved request to reload")
local reload = viewmodel.AnimationController:LoadAnimation(reloadAnim)
reload.Looped = false
reload:Play()
reload.Stopped:Wait()
print("reloaded")
game.ReplicatedStorage:WaitForChild("Values").AmmoAmount.Value = ammoamt
return ammoamt
end
function module.unequip(viewmodel, hold)
local HRP_Motor6D = viewmodel:WaitForChild("HumanoidRootPart").Handle
-- Unequip the gun by setting the Part1 of HRP_Motor6D to nil
HRP_Motor6D.Part1 = nil
-- Reset the viewmodel's CFrame to prevent it from being stuck to the player's head
viewmodel:SetPrimaryPartCFrame(game.Workspace.Camera.CFrame)
end
return module