How would I make a thick beam that damages players?

For my game I want to make a thicker beam type thing that would damage any players caught in it. (Think Lux ult from League of Legends.) But I’m wondering what the best method of doing this would be?

Would it be good to do like 3-5 raycasts to mirror the visual thing, or is there something else I can do? I had something like this in mind:

I’m not super sure how to approach this because I’ve never done anything like it before, so my apologies if this was the wrong place to post or anything or if this is a duplicate of a topic I couldn’t find. ^^

1 Like

Multiple ways:

Subdivide the length of the beam into X amount of equidistant points, then perform a magnitude check for players along each of the points

Use EgoMoose’s Rotated Region 3 Module to create a CFramed Region3 you can check for players in

Raycast to every single player simultaneously and then consider them ‘hit’ if the angle at which the ray was cast from the origin of the beam is within a certain threshold

3 Likes

You could just raycast a bunch, that would be easy to do and probably work fine. Didn’t test it, but this is an example of sending a rectangle of rays:

-- makes a (width*height)-grid of raycasts in the given direction
-- returns a table of all the RaycastResults which hit something
-- widthRays and heightRays are option, they represent how many rays to cast in each
-- axis - defaults to 1 per stud.
local function ThickRaycast(origin, dir, width, height, widthRays, heightRays)
	widthRays = widthRays or width
	heightRays = heightRays or height
	local cframe = CFrame.new(origin, origin+dir) -- there are better ways to get this but w/e

	local hitResults = {}

	for row = 1, heightRays do
		for col = 1, widthRays do
			local x = width * ((col - 1) / (widthRays - 1) - 0.5)
			local y = height * ((row - 1) / (heightRays - 1) - 0.5)

			local rayOrigin = cframe + cframe.RightVector * x + cframe.UpVector * y

			-- add params if you want
			local result = workspace:Raycast(rayOrigin, dir)

			if result ~= nil then
				table.insert(hitResults, result)
			end
		end
	end

	return hitResults
end

Another fun option might be to treat other players as spheres and perform some kind of cylinder-sphere intersection on them.

1 Like

Man, I know casting a ray is inexpensive performance-wise, but I just can’t help but shudder when I read that code :cold_face:

1 Like

I would bet that twenty simple c-side raycasts are faster than the lua-side GJK intersection checks that the rotated region3 module uses internally. Not knocking that module, it’s really cool and well made, but I think it’s overkill for this.

1 Like

You think so? RR3’s been pretty speedy no matter which end I require it from. I definitely have a bias against rays, though - bane of my existence for the years I’ve spent needing them in creating fighting games.

1 Like

Actually I changed my mind, rr3 or a similar approach would be better for this application because raycasts return the first hit thing and presumably OP wants the behavior to be more AOE.

1 Like

You could do it the really simple way to, which is to check if the player touched a part and if they do they can die,

However, doing the ray-casting option would be better quality wise, and don’t quote me on this but I think it is better for performance too.

1 Like

Thank you so much for your helpful answer! This is what I was looking for.

Thank you to everyone else for their replies too! ^^

1 Like
1 Like