Raycast breaks through walls

I just noticed I misread your post. I thought you meant they will go through if it’s not enabled. That is my bad.

1 Like

@zombi_vadim

I believe I solved it, though I altered some of the code the root fix is there at this line:

PlaceLaser.rbxl (81.9 KB)

some other changes included in debugging were making the beam not face camera, bruteforceallslow = true, cancollide all parts, changing up raycast code & making the entire lazerMount in the ignoredescendants just so you have a list of things that were altered.

Unfortunately, this is not the case. Start the level standing on the roof of the box and you will see how the laser passes through obstacles.

1 Like

Truly, Roblox is wonderful, there is no mistake in the position, but it is there.

-- try this updated version to see if it works k
local RunService = game:GetService("RunService")
local laserGunPart = script.Parent

local visualBegin = laserGunPart.StartAttachment
local visualEnd = laserGunPart.EndAttachment
local rcParams = RaycastParams.new()
rcParams.FilterDescendantsInstances = { laserGunPart }
rcParams.FilterType = Enum.RaycastFilterType.Blacklist
rcParams.IgnoreWater = true

local function onHeartbeat()
    local rayOrigin = laserGunPart.Position
    local rayDirection = laserGunPart.CFrame.LookVector * 150

    local raycastResult = workspace:Raycast(rayOrigin, rayDirection, rcParams)

    if raycastResult then
        visualEnd.Position = visualBegin.Position + rayDirection.Unit * raycastResult.Distance
    else
        visualEnd.Position = visualBegin.Position + rayDirection
    end
end

RunService.Heartbeat:Connect(onHeartbeat)

By. In addition to the fact that the laser shows it is unclear where, it still passes through walls.

Does the problem still occur if you bind to RenderStepped instead of Heartbeat? It looks to me like the end attachment update is lagging 1 frame behind the rotation of the laser, so the length of the beam ends up being the value that is correct for where the laser was aimed last frame. Or possibly it could be a frame ahead? I can’t say for sure because that laser gizmo is using truly ancient Roblox tech (RotateV and motor surfaces) that have been deprecated for nigh on 10 years. All bets are off as to when those instances update, as compared with current-day HingeConstraints and Motor6Ds.

I tried using a regular loop with a different delay, it didn’t change anything.

Right. So the difference between F8 and F5 is going to be whether the client is present or not and ultimately whether replication (aka network latency) needs to be accounted for.

This problem occurring only on the client and not the server suggests that something is happening at some point in the replication process causing the bug, (further supported by the use of onHeartbeat as you’ve bound raycasting - a resource intensive function - to be run every single frame).

If the issue is occurring despite the visualEnd.Position being correct for the raycast on the client, then this is likely a graphical (rendering) issue. Alternatively, if the visualEnd.Position does update to a spot that shouldn’t be possible per the rcParams then its likely an issue with the physics or computational aspect of replication.

What exactly is going wrong and/or why - im not sure. Some possible causes could be:

Fixing the issues means finding where the discrepancy is occuring, and your best bet to figure that out is by using the microprofiler and developer console.

Pre-Post Edit

This is my guess - although which one im not sure.

These likely update in the Legacy section of the task scheduler, which occurs after the render step, and that could be causing some mismatch between the visual rendering.

Oh, I only just noticed that your laser Script is a server script. So the lag is not a Runservice issue, just replication latency (which is 1 frame even in play solo, but will be your ping time in a published game!). The motors update client-side, but your raycast is done server-side, and the attachment position has to replicate.

The only way to make this look right is to do it all in a LocalScript or Script set to Client, not Server or Legacy. Legacy = server side execution. Visual effects that have to sync to the camera should always be done locally.

Try changing the Script RunContext from Legacy to Client. Then ideally, do the raycast on RenderStepped so that you know you have the latest visual position of the laser device when raycasting. That should fix it.

1 Like

I ran it on a local script, but nothing has changed. It’s starting to remind me of fortune telling on coffee grounds.

I optimized the code a little for better garbage collection. But yeah, here’s the fixed code:

-- Services
local RunService = game:GetService("RunService")

-- Functions
local function onHeartbeat()
	-- Setup
	local laserGunPart = script.Parent
	
	local visualEnd = laserGunPart.EndtAttachment
	local rcParams = RaycastParams.new()
	rcParams.FilterDescendantsInstances = {laserGunPart}
	rcParams.FilterType = Enum.RaycastFilterType.Exclude
	rcParams.IgnoreWater = true
	
	local maxDistance = 150
	local startL = laserGunPart.CFrame.Position
	local endL = startL + laserGunPart.CFrame.LookVector * maxDistance
	local rayDirection = (startL - endL) * maxDistance
	
	-- Ray
	local raycastResult = workspace:Raycast(startL, rayDirection, rcParams)

	if raycastResult then
		visualEnd.Position = Vector3.new(0,0,raycastResult.Distance)
		--visualEnd.WorldPosition = raycastResult.Position
	else
		print("!")
	end
end

-- Events
RunService.Heartbeat:Connect(onHeartbeat)

Doing it like this seemed to work much better, it no longer passes through walls, at least in my testing.

I ran the test in server-client mode and it is clearly visible that positioning is normal on the server, but the client calculates the position incorrectly.

No, it doesn’t work. The problem is not in the correct position, but in the client’s error.

So, to begin with, I redid the outdated physics of rotating parts, but it didn’t help.
But when I replaced the RunContext in the script with the Client, the glitch changed places, and now the laser passes through the walls on the server, and everything is fine on the client, which can be considered a solution to the problem.
I have only one question, when you just create a LocalScript, nothing changes, but when you switch the context, it works. Why?

A Script with RunContext = Client is the only kind of client script that can run from just anywhere in the Workspace. A LocalScript in a Model like this won’t execute at all, so you would still be seeing the results of the server script, replicated.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.