CyberMax
CyberMax › Answers

How to raycast in Roblox: a gun script the server checks

Updated 2026-10-17 · Roblox and game developers · by CyberMax

Short answer

Call workspace:Raycast(origin, direction * range, params), where params is a RaycastParams that excludes the shooter's character. For a gun, the client sends only the aim direction through a RemoteEvent; the server checks the fire rate and that the origin is near the player, casts the ray itself and applies the damage.

Copy-paste code

Server side of a hitscan gun

local WEAPON = { damage = 28, headshot = 1.5, range = 300, rpm = 600 }
local lastShot = {}

game.ReplicatedStorage.Shoot.OnServerEvent:Connect(function(player, origin, direction)
	if typeof(origin) ~= "Vector3" or typeof(direction) ~= "Vector3" then return end
	local char = player.Character
	local root = char and char:FindFirstChild("HumanoidRootPart")
	if not root then return end
	local now = os.clock()
	if now - (lastShot[player] or 0) < (60 / WEAPON.rpm) * 0.9 then return end -- fire rate
	lastShot[player] = now
	if (origin - root.Position).Magnitude > 10 then return end -- shot must start near the player

	local params = RaycastParams.new()
	params.FilterType = Enum.RaycastFilterType.Exclude
	params.FilterDescendantsInstances = { char }
	local result = workspace:Raycast(origin, direction.Unit * WEAPON.range, params)
	if not result then return end
	local hum = result.Instance.Parent:FindFirstChildOfClass("Humanoid")
		or (result.Instance.Parent.Parent and result.Instance.Parent.Parent:FindFirstChildOfClass("Humanoid"))
	if hum and hum.Health > 0 then
		local mult = result.Instance.Name == "Head" and WEAPON.headshot or 1
		hum:TakeDamage(WEAPON.damage * mult)
	end
end)

-- client: Shoot:FireServer(camera.CFrame.Position, mouse.Hit.Position - camera.CFrame.Position)

Good to know

The second Parent check catches hits on accessories (Handle inside an Accessory inside the character).

RaycastResult also gives Position and Normal, for bullet holes and impact effects (draw those on the client).

Salvowick FPS Combat Framework: A shooter where the server has the final word

from $12

Salvowick is the full server-authoritative FPS framework: semi and burst fire, reloads, recoil and bloom, headshots, falloff and armour, a killfeed, and checks on every shot, tested.

Secure checkout · 14-day fix-or-refund if it doesn't work as described (terms)

Questions

Why does my raycast hit my own character?

Add your character to FilterDescendantsInstances with FilterType Exclude.

Should damage be calculated on the client?

No. Any number the client sends can be faked; the server must compute damage.

Free: the Roblox Starter Kit

7 free Luau modules (damage, pets, shop formatting, admin audit log, tycoon guards and more) plus 3 free calculators, then 5 short emails with the scripting fixes we see go wrong most often.

You get one email to confirm first. Then the kit, and 5 short emails over two weeks. One-click unsubscribe in every email; we never share your address.

Related answers

Roblox round system: intermission, round timer and winnersA server loop for round-based games: wait for enough players, intermission countdown, teleport in, round timerRoblox admin commands script with ranks (for your own game)Add :kick, :tp and :speed admin commands to your own Roblox game with TextChatService, a rank check by UserId