A multi-hitting raycast

Hello people today I will be showing you how to make a multi-hitting raycast.

Here are some things I will be teaching you

  • What is a multi-hitting raycast?

  • How to make one

  • side notes

So lets begin!

First off!

What is a multi hitting raycast?

A multi hitting raycast would be basically a raycast that once it hits something continues to hit thing until it reaches its goal.

Such as when you have a laser for instance.

If you want it to hit everyone in-between the start and the goal, this is what you could use!

How to make it!

setup

First your going to need to make a module-script, and put it into ReplicatedStorage.
This way you can access it from both client and server.

Next just name it MultihitRaycastMod, or whatever you want!(In my case that’s just what I’m going to name it)

now lets start coding!

Coding

First we have to create the function in the module.
This is how we would do that.

local module = {}

function module.Raycast()
	
end


return module

Next we need to make some variables and stuff.

For starters we need to get the position 1 and position 2 so we can send the raycast.
To do this we must do:

function module.Raycast(po1,po2)
	
end

NOTE po1 is position 1 and po2 is position 2

we also need to get a table of parts.
The table will contain parts we want to ignore

function module.Raycast(po1,po2,ignoreParts)
	
end

Now lets start making it send the raycast!

Lets begin by making some params for the raycast!

	local params = RaycastParams.new()
	
	params.FilterDescendantsInstances = {ignoreTable}
	params.IgnoreWater = true
	params.FilterType = Enum.RaycastFilterType.Blacklist

this should be in the module BTW.

next lets make some values.
One to store the hit parts,
and to tell when the raycast reaches the goal

function module.Raycast(po1,po2,ignoreParts)
	local params = RaycastParams.new()
	
	params.FilterDescendantsInstances = {ignoreTable}
	params.IgnoreWater = true
	params.FilterType = Enum.RaycastFilterType.Blacklist
	
	local finished = false
	local hitItems = {}
	
end

Now that we have that lets make the raycast actually fire!!

first we need to make it so we keep firing raycasts till we reach are goal.

function module.Raycast(po1,po2,ignoreParts)
	local params = RaycastParams.new()
	
	params.FilterDescendantsInstances = {ignoreTable}
	params.IgnoreWater = true
	params.FilterType = Enum.RaycastFilterType.Blacklist
	
	local finished = false
	local hitItems = {}
	
    -- this is where we repeat until we reach the goal.
	repeat
		
	until finished
end

Now lets fire a raycast.

What this part of the code does is send out a raycast.
If we hit something we add it to the Hititems table, and to the ignoreparts table

If we dont hit anything then that means there are no objects so we make the function end

I also forgot to mention to add this:

local ignoreTable = {table.unpack(ignoreParts)}

Add this like right at the beginning of the function.

The code:

local module = {}

function module.Raycast(po1,po2,ignoreParts)
	local ignoreTable = {table.unpack(ignoreParts)}
	
	local params = RaycastParams.new()
	
	params.FilterDescendantsInstances = {ignoreTable}
	params.IgnoreWater = true
	params.FilterType = Enum.RaycastFilterType.Blacklist
	
	local finished = false
	local hitItems = {}
	
	repeat
		params.FilterDescendantsInstances = {ignoreTable}
		local raycast = workspace:Raycast(po1,po2 - po1,params)
		
		if raycast then
			-- we made a raycast!
			if raycast.Instance then
				-- we hit something.
				table.insert(hitItems,raycast.Instance)
				table.insert(ignoreTable,raycast.Instance)
				warn('Hit item '..raycast.Instance.Name)
			else
				-- there was nothing there.
				finished = true
			end
			task.wait()
		end
		task.wait()
	until finished
	task.wait()
	
	
end


return module

we then add return at the end so we can get all the hit items.

local module = {}

function module.Raycast(po1,po2,ignoreParts)
	local ignoreTable = {table.unpack(ignoreParts)}
	
	local params = RaycastParams.new()
	
	params.FilterDescendantsInstances = {ignoreTable}
	params.IgnoreWater = true
	params.FilterType = Enum.RaycastFilterType.Blacklist
	
	local finished = false
	local hitItems = {}
	
	repeat
		local params = RaycastParams.new()

		params.FilterDescendantsInstances = {ignoreTable}
		params.IgnoreWater = true
		params.FilterType = Enum.RaycastFilterType.Blacklist
		
		
		local raycast = workspace:Raycast(po1,po2 - po1,params)
		
		if raycast then
			-- we made a raycast!
			if raycast.Instance then
				-- we hit something.
				table.insert(hitItems,raycast.Instance)
				table.insert(ignoreTable,raycast.Instance)
				warn('Hit item '..raycast.Instance.Name)
			else
				-- there was nothing there.
				finished = true
				warn('Nothing hit!')
			end
			task.wait()
		else
			warn('No raycast')
			finished = true
		end
		task.wait()
	until finished == true
	task.wait()
	
	return hitItems
end


return module

Calling the function with code.

Now Im going to show you how to call the function/Use the function.

First you need a script.
In the script get the module.
In my case its in ReplicatedStorage

local mod = require(game:GetService('ReplicatedStorage'):FindFirstChild('Module'))

next we need to get the PO1 and PO2

local po1 = workspace.Start.Position
local po2 = workspace.Goal.Position

in my case I have to parts in the workspace called “Start” and “Goal”

Make sure if you are using a part that you do, part.Position

then we need a table with all the parts to ignore.

local mod = require(game:GetService('ReplicatedStorage'):FindFirstChild('Module'))

local po1 = workspace.Start.Position
local po2 = workspace.Goal.Position


local ignoreItems = {workspace.Start,workspace.Goal}

next we just need to do this to fire the function!

-- this uses all the data we give it and then sends the raycast.
local items = mod.Raycast(po1,po2,ignoreItems)

this will make the items variable a table filled with all the items that the raycast hits.

See it in action!

I made it so it deletes what ever parts it hits.

the blue part is the start, and the green one is the goal. Other parts are just parts in the way that we detect

Finished code.

I noticed how I missed somethings and changed it later so to help you, just copy this finished code

The code
local module = {}

function module.Raycast(po1,po2,ignoreParts)
	local ignoreTable = {table.unpack(ignoreParts)}
	
	local params = RaycastParams.new()
	
	params.FilterDescendantsInstances = {ignoreTable}
	params.IgnoreWater = true
	params.FilterType = Enum.RaycastFilterType.Blacklist
	
	local finished = false
	local hitItems = {}
	
	repeat
		local params = RaycastParams.new()

		params.FilterDescendantsInstances = {ignoreTable}
		params.IgnoreWater = true
		params.FilterType = Enum.RaycastFilterType.Blacklist
		
		
		local raycast = workspace:Raycast(po1,po2 - po1,params)
		
		if raycast then
			-- we made a raycast!
			if raycast.Instance then
				-- we hit something.
				table.insert(hitItems,raycast.Instance)
				table.insert(ignoreTable,raycast.Instance)
				warn('Hit item '..raycast.Instance.Name)
			else
				-- there was nothing there.
				finished = true
				warn('Nothing hit!')
			end
			task.wait()
		else
			warn('No raycast')
			finished = true
		end
		task.wait()
	until finished == true
	task.wait()
	
	return hitItems
end


return module```

side notes.

I will probably be updating this in the future.
If you have any requests feel free to tell me!

What would you rate this?
  • IVE BEEN DYING TO GET SOMETHING LIKE THIS!! 1000000 STARS
  • 5 stars
  • 4 stars
  • 3 stars
  • 2 stars
  • 1 stars

0 voters

9 Likes

Meant to give this five stars as it is a pretty solid guide :skull:, although I guess any newbies could make use a .rbxl with your example. Besides that, nicely written!

1 Like

I will probably make a file for it!
In some time lol

1 Like

Nice fro! Was making a ability based on ray hits and this is very useful, thank you!

1 Like