Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Why do I lose more value than what the script says to lose?

I have a gun, and it has an ammo value. Everytime I shoot the gun, it works fine.. I have the max amount of ammo (15). It shoots it all, then I reload and shoot it again, still, everything works.

But when I unequipt my gun, then I take it back, suddenly it shoots 8 bullets instead. And its like the ammo value changed from 15 to 8. The script tells the gun to lose only 1 bullet PER SHOT. But for some reason it loses way more ammo.

I tried making a ScriptModule to store the ammo there, same issue. I tried making a Value inside the gun script to store the ammo there, same issue. I tried making a Value inside the gun it senf (NumberValue) to store the ammo there, same issue.

LOCAL SCRIPT (Mostly the input framework, to send a remote events to the server script)

local shootremote = script.Parent:WaitForChild("ShootRemote")
local reloadremote = script.Parent:WaitForChild("ReloadRemote")

out = false

script.Parent.Equipped:Connect(function()
	out = true
	idle:Play() --this is an animation ignore it
	mouse.Button1Down:connect(function()
		shootremote:FireServer()
	end)
end)
script.Parent.Unequipped:Connect(function()
	out = false
	idle:Stop() --this is an animation ignore it
end)

uis.InputBegan:connect(function(key)
	if key.KeyCode == Enum.KeyCode.R then
		if out == true then
		reloadremote:FireServer()
		end
	end
end)

SERVER SCRIPT (The script that handles everything else, shooting, effects, reload.)

local ammo = script.Parent.Ammo.Value -- These both are the value of a number value inside the gun, this is the last method I tried to use, but as I said, didnt work, like the other 2 methods.
local clip = script.Parent.Clip.Value

function shoot(player)
	local char = player.Character
	local hum = char.Humanoid
	local came = game.Workspace.Camera
	
	local recoilanim = hum:LoadAnimation(anims.recoil)
	
	if ammo > 0 then
		main.Fire:Play()
		main.Flash.Enabled = true
		main.PointLight.Enabled = true
		recoilanim:Play()
		ammo = ammo - 1 --Here it says to lose ONLY ONE ammo.
		wait(0.1)
		main.Flash.Enabled = false
		main.PointLight.Enabled = false
		recoilanim:Stop()
	elseif ammo == 0 and reloading == false then
		main.Parent.Handle.empty:Play()
	end
end

reloading = false
function reload(player)
	local char = player.Character
	local hum = char:WaitForChild("Humanoid")
	
	local reloadanim = hum:LoadAnimation(anims.reload)
	
	if ammo == 0 and reloading == false then
		reloading = true
		reloadanim:Play()
		reloadanim:AdjustSpeed(1.2)
		wait(1)
		main.magin:Play()
		wait(0.5)
		reloadanim:Stop()
		wait(0.2)
		main.Parent.Handle.boltclose:Play()
		ammo = clip
		reloading = false
	elseif ammo < clip and reloading == false then
		reloading = true
		reloadanim:Play()
		reloadanim:AdjustSpeed(1.2)
		wait(1)
		main.magin:Play()
		wait(0.5)
		reloadanim:Stop()
		wait(0.2)
		ammo = clip
		reloading = false
	end
end

shootremote.OnServerEvent:Connect(function(plr)
	shoot(plr)
end)

reloadremote.OnServerEvent:Connect(function(plr)
	reload(plr)
end)

5 comments

0

use the Activated event instead of nesting Button1Down inside Equipped

0

Nope, still losing too much ammo.

0

wasnt a fix just a suggestion

0

When you have used :connect(), please try using :Connect() it may not fix it but will prevent bugs in the near future.

0

Oh, alright, thank you. :D

1 answer

✓ Accepted answer

I'm assuming the problem is, you're connecting the function that shoots the gun every time its equipped. It should be an easy fix, let me explain.

script.Parent.Equipped:Connect(function()
    out = true
    idle:Play()
    mouse.Button1Down:connect(function() -- connects the function to shoot.
        shootremote:FireServer()
    end)
end)

The above is your equip function in your LocalScript.

You see, when you connect an event (in this case, mouse.Button1Down:connect) the function will fire every time the event is fired. Once you've equipped the gun, it'll connect your click event to the shoot function, so from that point, every time your mouse is clicked, your shootremote:FireServer will run. So if you equip the gun twice, it'll connect your shooting function twice, therefore clicking once will fire two shooting functions, allowing you to shoot twice and lose twice the ammo.

There are a few of ways to fix this, but one thing is the same: We want only one shooting function firing when you shoot.

Fix 1:

You could disconnect the shooting function when your gun is unequipped. So if you equip the gun, it'll connect to your shooting function, then when you unequip your gun, the shooting function will be disconnected and won't run anymore until you connect it again.

script.Parent.Equipped:Connect(function()
    out = true
    idle:Play() --this is an animation ignore it
    shootfunction = mouse.Button1Down:connect(function() -- connects the function to shoot.
        shootremote:FireServer()
    end)
end)

script.Parent.Unequipped:Connect(function()
    out = false
    idle:Stop()
    shootfunction:Disconnect() -- disconnects the shooting function.
end)

Fix 2:

You could have the shooting function always connected, but it will only run if a certain requirement is met by using if statements. In this case, we want the requirement to be Gun is equipped so it will only shoot if the gun is equipped. Fortunately, you already have a variable that defines whether or not the gun is equipped, which is out.

mouse.Button1Down:Connect(function() -- connects the function to shoot.
    if out == true then -- if the gun is equipped,
        shootremote:FireServer() -- fires the shoot RemoteEvent.
    end
end)

script.Parent.Equipped:Connect(function()
    out = true
    idle:Play()
end)

script.Parent.Unequipped:Connect(function()
    out = false
    idle:Stop()
end)

Fix 3:

Use the Activated event. The Instance Tool has an event called Activated. it is fired whenever the tool is activated. In other words, it will fire when you click with the tool equipped. So we use this, make the gun shoot when it's activated.

script.Parent.Activated:Connect(function() -- connects the shooting function when the gun is activated.
    shootremote:FireServer() -- fires the shoot RemoteEvent.
end)

script.Parent.Equipped:Connect(function()
    out = true
    idle:Play()
end)

script.Parent.Unequipped:Connect(function()
    out = false
    idle:Stop()
end)

Edit: Try using :Connect() instead of :connect(), since :connect() is deprecated.

Sorry if you didn't understand my explanation, I hope it helped you in anyway.

If you have any questions, I'll try to answer them when I'm online.

2 comments

0

No no, you explained it perfectly. Thank you. Also I didnt even know "Disconnect" existed lmao thats new. Well learned something new today. Thank you again.

0

No problem.

This discussion is preserved as it was. New answers, comments, and votes are closed.