Introduction⚓︎
In this tutorial, we will be making a simple, blocky gun. This tutorial requires a basic knowledge of the following topics
It's highly recommended not to proceed if you haven't covered those topics.
Making a tool⚓︎
First of all, we will make a tool that will be our gun. Because this tutorial will only cover the fundamentals of a weapon, we will not emphasize the shape of the gun.
Add a part in Workspace and name it Handle.
Scale the part according to the hand of the player's character.
Now add a Tool in workspace and parent the Handle to the tool. Our explorer hierarchy now looks like this:
If you want to test, place your tool in StarterPack.
Click the play button (or press F5).
Setting Up⚓︎
Now we will set up everything we need for our weapon to work.
Add a Local Script in the tool. Add a Remote Event in the Replicated Storage. Add a Script in ServerScriptService.
Client Side⚓︎
On the client side (local script) we will check when the tool is used and request the server to shoot a bullet. First of all, we will store everything we need in variables to make the code look cleaner.
local gun = script.Parent -- our tool
local remote_event = game.ReplicatedStorage.RemoteEvent
local mouse = game.Players.LocalPlayer:GetMouse() -- getting the mouse of player
We will create a function shooter
. This function will be responsible for making requests when the tool is used. It will be done by firing the remote event on the server. This remote event will also carry the position where the player's mouse is pointing at.
local gun = script.Parent --our tool
local remote_event = game.ReplicatedStorage.RemoteEvent -- remote event
local mouse = game.Players.LocalPlayer:GetMouse() -- getting the mouse of player
local gun_connection -- variable for caching connection
local function shooter()
local mouse_pos = mouse.Hit.Position -- the 3d world position where the mouse is pointing.
local origin = gun.Handle.Position
remote_event:FireServer(mouse_pos, origin)
end
Now we will connect a function to the Equipped
event of the tool. In this function, we will connect the shooter function to the Activated
event of the tool. This connection will be cached in a variable gun_connection
so we can disconnect it as the tool is unequipped (the Unequipped
event is fired).
local gun = script.Parent -- our tool
local remote_event = game.ReplicatedStorage.RemoteEvent -- remote event
local mouse = game.Players.LocalPlayer:GetMouse() -- getting the mouse of player
local gun_connection -- variable for caching connection
local function shooter()
local mouse_pos = mouse.Hit.Position -- the 3d world position where the mouse is pointing.
local origin = gun.Handle.Position -- the origin of bullet
remote_event:FireServer(mouse_pos, origin)
end
gun.Equipped:Connect(function()
gun_connection = gun.Activated:Connect(shooter)
end)
gun.Unequipped:Connect(function()
gun_connection:Disconnect()
end)
Congrats! our client side is done. Every time tool is equipped the connection on the Activated
event is established and shooter
is called whenever the player clicks/activates the tool.
Server Side⚓︎
On the server side, we have the following things to do:
- Creating bullets.
- Setting up velocity constraint.
- Calculating directional vector
- Dealing damage.
- Destroying bullet.
But firstly, we have to check when the remote event is fired.
Creating Bullets⚓︎
You can create a bullet of any size, color, and shape you want. I will be creating blocky shape neon yellow bullets.
game.ReplicatedStorage.RemoteEvent.OnServerEvent:Connect(function(player, mouse_pos)
-- creating bullets
local bullet = Instance.new("Part")
bullet.Color = Color3.new(1, 1, 0.133333)
bullet.Size = Vector3.new(1,1,1)
end)
Setting Up Velocity Constraint⚓︎
We will use Linear Velocity to apply a continuous velocity on bullets. For doing so, we have to create an attachment and parent it to the bullet. Then we will create a LinearVelocity
constraint and assign the attachment to the Attachment1
property of LinearVelocity. It will be parented to bullet as well.
game.ReplicatedStorage.RemoteEvent.OnServerEvent:Connect(function(player, mouse_pos)
-- creating bullet
local bullet = Instance.new("Part")
bullet.Color = Color3.new(1, 1, 0.133333)
bullet.Size = Vector3.new(1,1,1)
bullet.CanCollide = false
-- creating attachment
local attachment = Instance.new("Attachment")
attachment.Parent = bullet
-- reating velocity constraint
local velocity = Instance.new("LinearVelocity")
velocity.Attachment0 = attachment
velocity.Parent = bullet
end)
Calculating Directional Vector⚓︎
Linear velocity requires a Vector3
value that specifies the direction of velocity. We need a vector that originates from the tool and points in the direction where the mouse of the player is pointing at.
game.ReplicatedStorage.RemoteEvent.OnServerEvent:Connect(function(player, mouse_pos, origin)
-- creating bullet
local bullet = Instance.new("Part")
bullet.Color = Color3.new(1, 1, 0.133333)
bullet.Size = Vector3.new(1,1,1)
bullet.CanCollide = false
-- creating attachment
local attachment = Instance.new("Attachment")
attachment.Parent = bullet
-- creating velocity constraint
local velocity = Instance.new("LinearVelocity")
velocity.Attachment0 = attachment
velocity.Parent = bullet
-- setting the direction of velocity
local speed = 50 -- speed of bullet/length of vector
velocity.MaxForce = 9e6 --setting maxforce to 0 exponent 9
local directional_vector = (mouse_pos - origin).Unit * speed
velocity.VectorVelocity = directional_vector
end)
Dealing Damage⚓︎
This is another important part of gun mechanics. We will use the Touched
event, as the bullet touches any object we will check its parent and search for a humanoid. If it succeeds in finding the humanoid then we are good to deal damage.
Warning
Always make sure that you are not damaging humanoid of shooter.
game.ReplicatedStorage.RemoteEvent.OnServerEvent:Connect(function(player, mouse_pos, origin)
-- creating bullet
local bullet = Instance.new("Part")
bullet.Color = Color3.new(1, 1, 0.133333)
bullet.Size = Vector3.new(1,1,1)
bullet.CanCollide = false
-- creating attachment
local attachment = Instance.new("Attachment")
attachment.Parent = bullet
-- creating velocity constraint
local velocity = Instance.new("LinearVelocity")
velocity.Attachment0 = attachment
velocity.Parent = bullet
-- setting the direction of velocity
local speed = 50 -- speed of bullet/length of vector
velocity.MaxForce = 9e6 -- setting maxforce to 9 exponent 9
local directional_vector = (mouse_pos - origin).Unit * speed
velocity.VectorVelocity = directional_vector
--deal damage
bullet.Touched:Connect(function(hit)
if hit.Parent ~= player.Character and hit.Parent:FindFirstChild("Humanoid") then
hit.Parent.Humanoid.Health -= 15
bullet:Destroy()
end
end)
bullet.Parent = workspace
bullet.Position = origin
end)
Destroying Bullet⚓︎
Lastly, we will destroy the bullet after a few seconds via debris service.
game.ReplicatedStorage.RemoteEvent.OnServerEvent:Connect(function(player, mouse_pos, origin)
--creating bullet
local bullet = Instance.new("Part")
bullet.Color = Color3.new(1, 1, 0.133333)
bullet.Size = Vector3.new(1,1,1)
bullet.CanCollide = false
--creating attachment
local attachment = Instance.new("Attachment")
attachment.Parent = bullet
--creating velocity constraint
local velocity = Instance.new("LinearVelocity")
velocity.Attachment0 = attachment
velocity.Parent = bullet
--setting the direction of velocity
local speed = 50 -- speed of bullet/length of vector
velocity.MaxForce = 9e6 --setting maxforce to nine exponent 9
local directional_vector = (mouse_pos - origin).Unit * speed
velocity.VectorVelocity = directional_vector
--deal damage
bullet.Touched:Connect(function(hit)
if hit.Parent ~= player.Character and hit.Parent:FindFirstChild("Humanoid") then
hit.Parent.Humanoid.Health -= 15
bullet:Destroy()
end
end)
bullet.Position = origin
bullet.Parent = workspace
game.Debris:AddItem(bullet, 8)
end)
Closing⚓︎
I hope this tutorial helped you and gave you an idea of how you can design your shooting weapons. You can customize it a lot by changing bullets, shooting styles, and stuff. Thanks a lot for reading! Byee!