Hello everyone and this is the fourth part to the fps tutorial. Its the part about reloading!
Disclaimer: I am not a beginner in the FPS world anymore but I still make mistakes! In this part I will show you how I did it so please don’t tell me that its the wrong way. I also recommend you read every single word as this is complex and not for beginners.
In this part we will make the gun reload.
Its been a long time coming and was rewritten a few times hence it took so long. Without further I do, we shall begin!
1. Preparation
-
First you will need to make a decision on how to make the reloading ex. you drop the mag when reloading, you have stored ammo, unlimited stored ammo just to name a few.
In this tutorial we will make it so you have unlimited stored ammo, but it will be easy to customize to have limited stored ammo. -
Now how will we make it? Here’s how it works:
Since we are making it so we have unlimited stored ammo it will look a bit different. -
Lets get to setting up the game!
Inside our gun settings we will need a few variables:
Settings.storedammo = math.huge --the stored ammo aka backpack math.huge is infinate
Settings.magsize = 30 --ammo that the gun can hold
Settings.currentammo = 30 --ammo that the gun currently holds
We will also need to make the gun lose ammo when shooting, put this inside the mousebutton1down:
if weaponmodule.currentammo > 0 then
fire()
end
That’s it for the settings for now. Lets head to the framework
2. The Logic
- Now we will be going into the framework and transferring the logic there.
To start of we will make a function called reload() in the framework somewhere below the fire function.
function reload()
--we will add code here in a moment
end
So the first thing we need to do as shown in the diagram - make the gun not shoot, and how do we do that? By making a new bool called canfire and setting it to true:
local canfire = true
Now we have to make the gun check if the variable is true to shoot, we will do it like this:
mouse.Button1Down:Connect(function()
if weaponmodule.currentammo > 0 and canfire then --this just means if canfire == true but we are saving space
fire()
end
end)
Now if we were to set canfire to false our gun wouldn’t shoot, brilliant.
Lets get back on track again, so inside the reload function set the canfire to false just like this:
function reload()
canfire = false
end
Now for the second point we need to check if the gun has enough stored ammo to reload, there are two ways to do it - the first one to just check if stored ammo is higher or equal to our magazine size or the second to check if the stored ammo is higher than 0, this way we will need to do some extra math inside the reload function but it is much more preferred by FPS developers.
For this tutorial I will show you the first way, let’s get back on topic and check if stored ammo is higher than 0 inside the reload function:
function reload()
canfire = false
if weaponmodule.storedammo >= weaponmodule.magsize and weaponmodule.currentammo < weaponmodule.magsize then
--here we will put our reload code
end
end
Now that we have that logic going on we will go to the actual reloading logic part of the logic:
- Play reload animation
- Minus stored ammo
- Restore the current mag to its full capacity
Animation
First we will need a variable for the animation id in the module:
local Settings = {}
Settings.maincf = CFrame.new(0, -1, 0.5) * CFrame.Angles(0 ,0, 0)
Settings.aimcf = CFrame.new(-0.58,0.1, 2) * CFrame.Angles(0,0,0)
Settings.idleanim = "rbxassetid://6339207070"
Settings.reloadanim = "rbxassetid://7016589629"
Settings.storedammo = 500
Settings.magsize = 30
Settings.currentammo = 30
Settings.reloadtime = 3
return Settings
Then we will need to load it and play it inside our reload function:
local reload = Instance.new("Animation", currentweapon)
reload.AnimationId = weaponmodule.reloadanim
local reloadanim = currentweapon:WaitForChild("Humanoid"):LoadAnimation(reload)
reloadanim:Play()
We are done with our animation.
Minus stored ammo
We can do that very easily inside our if statement:
function reload()
canfire = false
if weaponmodule.storedammo >= weaponmodule.magsize and weaponmodule.currentammo < weaponmodule.magsize then
local reload = Instance.new("Animation", currentweapon)
reload.AnimationId = weaponmodule.reloadanim
local reloadanim = currentweapon:WaitForChild("Humanoid"):LoadAnimation(reload)
reloadanim:Play()
weaponmodule.storedammo -= weaponmodule.magsize
end
end
Reseting the mag to full
This is also very easy and we can do it after we minus the stored ammo like this:
function reload()
canfire = false
if weaponmodule.storedammo >= weaponmodule.magsize and weaponmodule.currentammo < weaponmodule.magsize then
local reload = Instance.new("Animation", currentweapon)
reload.AnimationId = weaponmodule.reloadanim
local reloadanim = currentweapon:WaitForChild("Humanoid"):LoadAnimation(reload)
reloadanim:Play()
weaponmodule.storedammo -= weaponmodule.magsize
weaponmodule.currentammo = weaponmodule.magsize
end
end
A couple of additions
Just to make this more flexible and actually work we will add reloading time:
--inside the module
local Settings = {}
Settings.maincf = CFrame.new(0, -1, 0.5) * CFrame.Angles(0 ,0, 0)
Settings.aimcf = CFrame.new(-0.58,0.1, 2) * CFrame.Angles(0,0,0)
Settings.idleanim = "rbxassetid://6339207070"
Settings.reloadanim = "rbxassetid://7016589629"
Settings.storedammo = 500
Settings.magsize = 30
Settings.currentammo = 30
Settings.reloadtime = 3 --make sure its about as longs as the animation
return Settings
Then we will add a wait inside the if statement
if weaponmodule.storedammo >= weaponmodule.magsize and weaponmodule.currentammo < weaponmodule.magsize then
local reload = Instance.new("Animation", currentweapon)
reload.AnimationId = weaponmodule.reloadanim
local reloadanim = currentweapon:WaitForChild("Humanoid"):LoadAnimation(reload)
reloadanim:Play()
weaponmodule.storedammo -= weaponmodule.magsize
weaponmodule.currentammo = weaponmodule.magsize
wait(weaponmodule.reloadtime)
end
And we also need to make sure you can fire after the reload:
function reload()
canfire = false
if weaponmodule.storedammo >= weaponmodule.magsize and weaponmodule.currentammo < weaponmodule.magsize then
local reload = Instance.new("Animation", currentweapon)
reload.AnimationId = weaponmodule.reloadanim
local reloadanim = currentweapon:WaitForChild("Humanoid"):LoadAnimation(reload)
reloadanim:Play()
weaponmodule.storedammo -= weaponmodule.magsize
weaponmodule.currentammo = weaponmodule.magsize
wait(weaponmodule.reloadtime)
reloadanim:Stop() --we stop the animation if we can already shoot
reload:Destroy() --not really good practice but its better than leaving it there
end
canfire = true --we add it here so if you cant reload you can still fire after pressing R
end
3. User Input Service
Finally we reached a new section of the tutorial, in this section we will make it so when you press the key R you will reload!
User Input Service
Because we have never used UIS (User Input Service) we will need to set it up i.e. get the service and use one of the three input states, you can read about user input service here.
First we will make a variable for it in the framework (you should have it, but still check):
local plr = game.Players.LocalPlayer
local char = plr.Character
local mouse = plr:GetMouse()
local cam = workspace.CurrentCamera
local runs = game:GetService("RunService")
local uis = game:GetService("UserInputService") --because its a service we need to get it with game:GetService()
local rs = game.ReplicatedStorage
local gunmodels = rs:WaitForChild("models")
local gunmodules = rs:WaitForChild("modules")
local resources = rs:WaitForChild("resources")
Getting The Input
Now we will use one of the user input service functions, we will use input began:
uis.InputBegan:Connect(function(input, gameprocessed)
if not gameprocessed then --this checks if the -player is not typing in chat
end
end)
Now we will check if the input is the key R with keycode:
uis.InputBegan:Connect(function(input, gameprocessed)
if not gameprocessed then
if input.KeyCode == Enum.KeyCode.R then
reload()
end
end
end)
And that is it!!!
Now your gun should reload if your magazine is not full and not shoot if its empty.
4. Outro
In the next tutorial we will make our system more user friendly by adding ui and sounds as well as making walking animations running ect., basically making it beautiful.
Some useful links that were in this tutorial:
User Input Service
My Links
FPS Tutorial Part 1
FPS Tutorial Part 2
FPS Tutorial Part 3
The Uncopylocked Game
My discord if very needed: Stormtrooperhelmet#9491
Thank you very much for all of the likes on the previous ones and because you made it to the end here’s a cookie