Help with raycasting logic

Okay, so I’ve been working on a little side project, and I need a (2D) raycasting based function. So what the function needs to do, is return a Y or X difference from the given point, to the “closest” floor. More specifically, if the point is inside collision, it finds the floor at the top of the collision. Otherwise, it finds the floor below. The issue is, I can’t just raycast up to check for a floor, because what if it’s inside a group of part… Okay, maybe this needs some images.


As you can see, when it’s outside of collision, it works perfectly fine. But when it’s inside, what do I do? I can’t cast down, that returns the bottom, but if I cast up, it returns the middle of the collision. How do I handle this, the intended result is this.
image

1 Like

why not use FindPartOnRayWithIgnoreList()

that doesn’t have anything to do with the question, though

your wording is kind of confusing i thought you had a part that was blocking another part you wanted to raycast so i was saying u could just ignore that part

I don’t understand what the triangles and rectangles are supposed to be. And what do you mean by a “floor” and being inside/outside a “collision.”

1 Like

the triangles and rectangles are supposed to be parts, a floor is basically a surface facing opposite to the direction of the ray, and inside/outside collision is inside/outside the parts

So if I understand correctly, you want to find the point at the top of the group of parts, whereas your current solution gets stick inside the group of parts.

To do this, you should do a second raycast beginning at the first raycast’s hit point. If you don’t hit anything, you’re done. Bit of you do, you’re still stuck inside the group of parts. So then perform a third raycast at the second raycast’s hit point, etc.

EDIT: I’m not sure if that makes sense. I can draw a diagram in the morning if you’d like.

but then what if it hits a ceiling afterwards

You’ve got me stumped there. I thought about it for a bit and I don’t know. You could combine clusters of parts into one polygon and instead find the top-most point of that one polygon.

i made similar raycasting tool

local tool = script.Parent
local player = game:GetService("Players").LocalPlayer
 
tool.Equipped:connect(function(mouse)
	print("Tool equipped!")
	
	mouse.Button1Down:connect(function()
		print("Mouse pressed!")
		local ray = Ray.new(tool.Handle.CFrame.p, (mouse.Hit.p - tool.Handle.CFrame.p).unit * 300)
		local part, position = workspace:FindPartOnRay(ray, player.Character, false, true)
		
		local light = Instance.new("Part", workspace)
		light.BrickColor = BrickColor.new("Bright red")
		light.FormFactor = "Custom"
		light.Material = "Neon"
		light.Transparency = 0.25
		light.Anchored = true
		light.Locked = true
		light.CanCollide = false
		
		local distance = (tool.Handle.CFrame.p - position).magnitude
		light.Size = Vector3.new(0.3, 0.3, distance)
		light.CFrame = CFrame.new(tool.Handle.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(30)
			end
		end
	end)
end)

That’s just a generic raygun script

2 Likes

Add the ceiling parts to the IgnoreList? If you are trying to do it "2D’ then just make sure every ray shares the same y coordinate for the beginning and ending positions every time. It is still kind of confusing what you are saying, though, so sorry if this doesn’t help.

You can’t ignore specific surfaces in roblox to my knowledge