I am having a little trouble with this gun script

Hello everyone! I want to learn about making a gun that shoots a ray. So I searched up this tutorial so then I can look over it and then try to make a gun on my own. But I don’t understand some parts in this script, can you guys help me? There are 3 different scripts and a remote event. The server and local script are in the tool and then there is a module script that does the bullet. I am only going to ask questions about the module script because I understand the other 2 but I’ll put them up anyway just in case.

The server script

-- variables for the firing for the laser
local tool = script.Parent
local canFire = true
local maxDistance = 100
local damage = 10
local shootTime = 3
local color = "Bright red"
local LaserSound = script.Parent.LaserSound

local GlobalFunctions = require(game.ServerScriptService.GlobalFunctions)
-- fires laser that runs by the remote event
function FireLaser(player, mouseHit)
	if canFire == true then
		LaserSound:Play()
		GlobalFunctions.shootLaser(player, mouseHit, tool, maxDistance, damage, color)
		canFire = false
		wait(shootTime)
		canFire = true
	end
end
tool.FireLaser.OnServerEvent:Connect(FireLaser)

The local script


-- variables
local tool = script.Parent
local LaserSound = script.Parent.LaserSound
-- on equipped function that when the weapon is equipped 
function OnEpuipped(mouse)
	-- local player and its humanoid component
	local player = game:GetService("Players").LocalPlayer
	local humanoid = player.Character:WaitForChild("Humanoid")
	--function on clicked that runs when the mouse is clicked
	
	local function OnClick()
		-- if statement that checks to see if the plaer is alive so he/she can fire the laser.
		if (humanoid.Health > 0) then
			tool.FireLaser:FireServer(mouse.Hit)
			LaserSound:Play()
		end
		
	end
	mouse.Button1Down:Connect(OnClick)
	
end
tool.Equipped:Connect(OnEpuipped)

The module script


local GlobalFunctions = {}


function GlobalFunctions.shootLaser(player, mouseHit, tool, maxDistance, damage, color)
	
	local ray = Ray.new(tool.Tip.CFrame.p, (mouseHit.p - tool.Tip.CFrame.p).unit * maxDistance) -- this is for question 1
	local part, position = workspace:FindPartOnRay(ray, player.Character, false, true) -- this is for question 2
	
	local beam = Instance.new("Part", workspace)
	beam.BrickColor = BrickColor.new(color)
	beam.FormFactor = "Custom"
	beam.Material = "Neon"
	beam.Transparency = 0.25
	beam.Anchored = true
	beam.Locked = true
	beam.CanCollide = false
	
	
	local distance = (tool.Tip.CFrame.p - position).Magnitude
	if (distance > maxDistance) then
		distance = maxDistance
	end
	
	
	beam.Size = Vector3.new(0.3, 0.3, distance)
	beam.CFrame = CFrame.new(tool.Tip.CFrame.p, position) * CFrame.new(0, 0, -distance/2)
	
	game:GetService("Debris"):AddItem(beam, 0.1)
	
	if part then
		local humanoid = part.Parent:FindFirstChild("Humanoid")
		
		if not humanoid then
			humanoid = part.Parent.Parent:FindFirstChild("Humanoid")
		end
		
		if humanoid then
			humanoid:TakeDamage(damage)
		end
	end
	
	
end

return GlobalFunctions

question #1

local ray = Ray.new(tool.Tip.CFrame.p, (mouseHit.p - tool.Tip.CFrame.p).unit * maxDistance) -- this is for question 1

On this variable the “(mouseHit.p - tool.Tip.CFrame.p).unit” part confuses me a little bit, I know that magnitude will get the position between to parts, but why did they use unit?

question 2

local part, position = workspace:FindPartOnRay(ray, player.Character, false, true) 

I understand the FindPartOnRay function, but I was just wondering why they put to thing in this variable(the part, position)

question 3

beam.Size = Vector3.new(0.3, 0.3, distance)
	beam.CFrame = CFrame.new(tool.Tip.CFrame.p, position) * CFrame.new(0, 0, -distance/2)

the " beam.CFrame = CFrame.new(tool.Tip.CFrame.p, position) * CFrame.new(0, 0, -distance/2)" confuses me, I think what’s happening is that we are teleporting the ray to the tip but it will teleport the middle of it, so we are moving the ray a little up so then the back of the ray will go on tip thus, making it shoot like a normal gun. I was just wondering how this calculates this. Like why are they multiplying or doing -distance/2. This may be confusing and I am sorry for any problems.

Please forgive my spelling mistakes and my grammar, I am still in school.

Because they aren’t try to get the distance between them, simply the direction. To my knowledge i think unit converts a vector into a single digit for multiplying. Basically they are getting the direction and multiplying it by the bullet / ray range.

Because FindPartOnRay Returns multiple things and there are just storing them in the same line.

1 Like

.Unit is the direction a of a vector. Multiplying it gives you a position that is x studs in that direction.

When it says part, position, that means the function returns two values, being a part and a position.

3 Likes

So then why did they times it by the max distance?(forgot to include this, sorry)

local ray = Ray.new(tool.Tip.CFrame.p, (mouseHit.p - tool.Tip.CFrame.p).unit * maxDistance) -- this is for question 1

Like @elliee_banana said,

So thats how far the ray will go

Try to change 'local ray = Ray.new(tool.Tip.CFrame.p, (mouseHit.p - tool.Tip.CFrame.p).unit * maxDistance)' to 'local ray = Ray.new(tool.Tip.CFrame.Position, (mouseHit.Position - tool.Tip.CFrame.Position).Unit * maxDistance)'