Raycast detecting curvy terrian

So im currently for my community trying to make a system where you can place lines down. These lines will allow you to fire once the player stands on then. My friend did something similar and he told me he used raycasting to make the line.

Example:
https://gyazo.com/e1f220b176f57be6d1e37f5e5c50120a

As you see the line goes with the terrian, and curves with it.

How can I achieve this any help loved!

Consider a line segment between the space above point A and above point B. If you go along this line segment in steps of e.g. 1 stud, you can raycast downwards from a bunch of points along that line to see where you should place the endpoints of the Beams that make up the curved line. Move all the beams up a tiny bit, like 0.25 studs. Otherwise they might clip when the curvature changes too fastimage

1 Like

May you explain a little more and include how I can do this with code? Include sources etc I can use. Also another question is by beam do you mean the beam in roblox?

This seemed like a fun idea so I went ahead and tried to create a quick proof of concept that you can expand upon.

I used @ThanksRoBama’s idea of raycasting every so often between two points, and connecting waypoints along the way with a beam. Here is a gif of the finished result: https://streamable.com/ne2s2n

Here is the commented script I used: (LocalScript in StarterCharacterScripts)

-- Variables
local Player = game.Players.LocalPlayer
local Mouse = Player:GetMouse()
local StartingPos

-- Overly complicated part at position - used to create beams
local function partAtPos(pos)
	local p = Instance.new("Part")
	p.Anchored = true
	p.Size = Vector3.new(1, 1, 1)
	p.Position = pos + Vector3.new(0, .5, 0)
	p.Orientation = Vector3.new(0, 0, 90)
	Instance.new("Attachment", p)
	p.Transparency = 1
	p.CanCollide = false
	p.Parent = workspace
	return p
end

-- set new starting point on mouse press
Mouse.Button1Down:Connect(function()
	StartingPos = Mouse.Hit.p
end)

-- create a line on mouse release
Mouse.Button1Up:Connect(function()
	-- neccesary variables
	local EndingPos = Mouse.Hit.p
	local Direction = EndingPos - StartingPos -- used to follow line from start to end
	local Distance = (StartingPos - EndingPos).Magnitude
	
	-- follow a line from start to end, creating a waypoint every stud
	local waypoints = {}
	for i = 1, Distance do
		-- raycast downwards at every point, creating a part (waypoint)
		local rayOrigin = StartingPos + (Direction*i)/Distance + Vector3.new(0, 20, 0) -- fancy math to follow the line
		local ray = Ray.new(rayOrigin, Vector3.new(0, -100, 0))
		--local part, position = workspace:FindPartOnRayWithIgnoreList(ray, waypoints) -- use this to detect parts, but expand upon ignorelist with all player's Characters
		local part, position = workspace:FindPartOnRayWithWhitelist(ray, {workspace.Terrain}) -- only place waypoints on terrain
		table.insert(waypoints, partAtPos(position))
	end
	
	-- go through the way points, connecting them with beams
	for i = 1, #waypoints - 1 do
		local Beam = Instance.new("Beam", waypoints[i])
		Beam.Attachment0 = waypoints[i].Attachment -- attachments added in partAtPos
		Beam.Attachment1 = waypoints[i + 1].Attachment
		Beam.FaceCamera = true -- this is lazy and you should tinker with how the beam is shown
	end
end)

Now, this is far from perfect. Using mouse position, this is client sided. You will need to do some replication onto the server. I also didn’t bother to remove the previous line, but you can do that easily by just deleting the waypoints. The line isn’t being drawn with the mouse as it moves either, but you can connect the draw function to a loop while mouse1 is being held. The ignorelist for the raycast only covers the waypoints, so players between the two endpoints will affect the line (You can add every player’s Character to the ignore list to fix this).

This should be more than enough to get you started, but just ask if I need to further clarify the process of my code.

EDIT: Changed the raycast from an ignorelist of the waypoints to a whitelist of the terrain (assuming this is meant to be used on an all terrain map.

1 Like

Thank you very much this helped a lot!

1 Like

Closed at request of author.