How to make a raycasting gun

tool.Activated:Connect(function()
remote:FireServer(cursor.Hit.Position)
end)
Change this to make it so that everytime the mousebutton2 button is held down fire a bullet. This can be done using RunService.Heartbeat (for constant checking) and UserInputService:IsKeyDown() to check if the key is down.

And if it is down then tell the server to fire.

4 Likes

I recommend something like this

local TriggerPulled = false

UserInputService.InputBegan:Connect(function(input)
if input.KeyCode == Enum.KeyCode.MouseButton1 then
TriggerPulled = true
end)

UserInputService.InputEnded:Connect(function(input)
if input.KeyCode = Enum.KeyCode.MouseButton1 then
TriggerPulled = false
end)

while TriggerPulled == true do
ā€“ insert gun shooting mechanics here

6 Likes

How would I make the bullet fly towards where you shot at rather than it being a beam?
Great tutorial also!

2 Likes

How would I get it to update and fire from the shoot part if the character is moving?
Also, is there a way I can add entire teams to this RaycastParams function?

2 Likes

FilterDescendantsInstances is a table so I guess you can just iterate over the team and add their characters to it.

2 Likes

Bullet isnt working, dunno why.

4 Likes

Instead of cloning a gun from ServerStorage you can just use instance.new, but i agree cloning the Part from serverstorage is more useful and easier than using Instance.new

Edit: to answer for the post above me, im not sure but
Bullent_Clone.Size or Bullet_Clone.CFrame might be the cause of it

3 Likes

you should just clone the bullet and use bullet.Velocity = bullet.CFrame.look vector * speed

4 Likes

Because when you shoot backwards the ray just detects your arm or the gun model so it doesnt work but it should work if you shoot in front of you

3 Likes

This tutorial is made really Great! I like this tutorial! . Good job this it reminds me alot of prison life.!

2 Likes

How would I be able to make an automatic gun with this tutorial?

4 Likes

No. Raycasting on the server is completely fine, it isnā€™t ā€œwastefulā€.

Replicating to the client is completely useless and wasteful, you donā€™t want someone spam shooting the gun and fire loads of remotes to clients causing high network usage.

Also do know that you would be firing remote events to all the players in the game, which is even more wasteful in network usage, considering you will have more than 1 person with the gun.

EDIT:

Also, this tutorial is just for those to get started, not to account for details as incapaz stated.

4 Likes

A single ray has an insignificant impact on the serverā€™s performance. You can usually shoot around 10-50 rays per frame on the server without causing any lag (donā€™t quote me on this as Iā€™ve only tested this once).

2 Likes

Hey there, would there be any way to add a headshot multiplier to it?

2 Likes

All you need to do is sense if the head has been kick and then do custom damage from there

2 Likes

basically check if the part being hitted is a Head using if statement in the raycast result line

3 Likes

Great tutorial, there has probably not been a reply in a very long time, so sorry for the interruption, but if you have the time, I want to understand this and I was wondering if you can answer me a few questions

  1. on the frontend script
local tool = script.Parent
local remote = tool:WaitForChild("OnShoot")

local Players = game:GetService("Players")
local client = Players.LocalPlayer
local cursor = client:GetMouse() 

tool.Activated:Connect(function()
	remote:FireServer(cursor.Hit.Position) -- this is the part I am talking about
end)

so when it says cusor.Hit.Position, when you say (custor.HIT.Position) is that what the mouse is clicking on? and then we are sending it to the backend script?

  1. on the backend script
local tool = script.Parent
local shoot_part = tool:WaitForChild("Shoot")
local remote = tool:WaitForChild("OnShoot")

local Workspace = game:GetService("Workspace")

remote.OnServerEvent:Connect(function(player, position) -- this is what I am talking about
	-- Nothing
end)

ok so you getting some variables from the frontend script and you it seems to me you are getting the position, and the player. But your frontend script dosenā€™t have a position and player variable, so can you explain that part to me?

  1. The backend script
local tool = script.Parent
local shoot_part = tool:WaitForChild("Shoot")
local remote = tool:WaitForChild("OnShoot")

local Workspace = game:GetService("Workspace")
local ServerStorage = game:GetService("ServerStorage")

remote.OnServerEvent:Connect(function(player, position)
	local origin = shoot_part.Position
	local direction = (position - origin).Unit -- this is the part I don't understand
	local result = Workspace:Raycast(shoot_part.Position, direction*300)
end)

ok this is a short one, I understand that you are casting a ray at the shoot part or the tip of the gun and getting the position, and then firing it * 300 studs, but the direction variable, I looked at the intro to raycasting on the dev forum, and I can see you are calculating the direction, but in the end the unit part, what is that? And what is it used for?

  1. In the backend script

local tool = script.Parent
local shoot_part = tool:WaitForChild("Shoot")
local remote = tool:WaitForChild("OnShoot")

local Workspace = game:GetService("Workspace")

remote.OnServerEvent:Connect(function(player, position)
	local origin = shoot_part.Position
	local direction = (position - origin).Unit
	local result = Workspace:Raycast(shoot_part.Position, direction*300)
	
	local intersection = result and result.Position or origin + direction*300 -- this is what I am talking about
end)

I am just downright confused on this part, why did you put result and result.Position? Can you just explain this part a little more?

  1. in the backend script
local tool = script.Parent
local shoot_part = tool:WaitForChild("Shoot")
local remote = tool:WaitForChild("OnShoot")

local Workspace = game:GetService("Workspace")
local ServerStorage = game:GetService("ServerStorage")

remote.OnServerEvent:Connect(function(player, position)
	local origin = shoot_part.Position
	local direction = (position - origin).Unit*300
	local result = Workspace:Raycast(origin, direction)
	
	local intersection = result and result.Position or origin + direction -- this is another part
	local distance = (origin - intersection).Magnitude -- this is the part 
	
	local bullet_clone = ServerStorage.Bullet:Clone()
	bullet_clone.Size = Vector3.new(0.1, 0.1, distance)
	bullet_clone.CFrame = CFrame.new(origin, intersection)*CFrame.new(0, 0, -distance/2)
	bullet_clone.Parent = Workspace
end)

I donā€™t know if this part was already explained, but first, what is does intersection stand for? And why is it used in the distance variable?

and thatā€™s all, the rest I completely understand

thanks for reading! :slight_smile:

2 Likes

cursor.Hit.Position returns a Vector3


Both the backend and the frontend scripts are under the tool, there is no need for the frontend script to have the variable shoot_part.


.Unit returns the normalized vector. Meaning that you take the existing vector and reduce it to the length of one (which we can multiply by 300 to create a ray that is the length of 300). .Unit effectively does this How to Normalize a Vector - YouTube


This is a ternary operation in lua. Itā€™s the equivalent of this

local intersection
if result ~= nil then
    intersection = result.Position
else
    intersection = origin + direction*300
end

Intersection stands for where where the ray hits.

2 Likes

@sjr04
I have one question:

how you can make raycasting with beams using attachments?

basicly the problem is this:

image (when you walk)

Roblox network milisecound delay(when fire the RemoteEvent) this looks kinda bad but I am trying to find one way for fix this and I think if I use beams with attachments (doing damage) can work. Any idea how I can make something like that?

4 Likes

are you using RunService or While True Do

1 Like