How can I move an object in the same direction a raycast would when nothing is detected by one?

In my game, I have a laser that uses a raycast to determine where to put the end of a laser beam when it collides with a part every frame. This works fine until there’s nothing for the raycast to hit; when that happens, the end of the laser beam gets stuck at the last position the raycast hit. I’ve searched all across the forum and I can’t find a solution that works. What can I do to move the end of the beam in the same direction the raycast would when it doesn’t hit anything?

(The laser should be able to rotate and move while keeping this effect.)

Current result:

Desired result:


(I simulated this in studio by moving the attachment used by the beam object.)

This is the code for it:


local rs = game:GetService("RunService")
local laserOutputPart = script.Parent -- The reference part for the lookvector
local laserPoint = laserOutputPart.Parent.Parent.laserPoint -- A part that holds the attatchment for the end of the beam, as well as some particles

rs.RenderStepped:Connect(function(dt)
	local rayOrigin = laserOutputPart.Position
	local rayDirection = laserOutputPart.CFrame.LookVector
		local raycastResult = workspace:Raycast(rayOrigin, rayDirection * 5000)
	
	if raycastResult then
		laserPoint.CFrame = CFrame.new(raycastResult.Position) * CFrame.Angles(math.rad(raycastResult.Normal.X), math.rad(raycastResult.Normal.Y), math.rad(raycastResult.Normal.Z)) -- (edit) The CFrame.Angles(...) part just makes the particle emitters line up with the angle of the object they're hitting, it's really just the first part of this line that matters
	else
      -- (edit) Here it would theoretically move the laserPoint part somewhere to achieve the desired effect
end)
1 Like

Does it have something to do with CFraming the laser point?

Edit: it seems to not revert the laser point’s position

No, that’s just for what happens when the raycast does hit something as shown in the gif below

RobloxStudioBeta_98BGpxshNG

try this:

local rs = game:GetService("RunService")
local laserOutputPart = script.Parent -- The reference part for the lookvector
local laserPoint = laserOutputPart.Parent.Parent.laserPoint -- A part that holds the attatchment for the end of the beam, as well as some particles

rs.RenderStepped:Connect(function(dt)
	local rayOrigin = laserOutputPart.Position
	local rayDirection = laserOutputPart.CFrame.LookVector
		local raycastResult = workspace:Raycast(rayOrigin, rayDirection * 5000)
	
	if raycastResult then
		laserPoint.CFrame = CFrame.new(raycastResult.Position) * CFrame.Angles(math.rad(raycastResult.Normal.X), math.rad(raycastResult.Normal.Y), math.rad(raycastResult.Normal.Z)) -- (edit) The CFrame.Angles(...) part just makes the particle emitters line up with the angle of the object they're hitting, it's really just the first part of this line that matters
	else
        laserPoint.CFrame = CFrame.new(rayDirection * 5000)
    end
end)
3 Likes

That works great! The only issue is that it sort of gets crooked when it stops detecting an object and it goes through walls if the angle is set correctly.
RobloxStudioBeta_mPwzllUqsu

(Edit) I’ve noticed this becomes quite an issue at long distances, is anyone aware of what’s causing this?
RobloxStudioBeta_oHptQ4RlOz