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.