Hey, so I’m trying to make a realistic sound system and I’ve come to a good point, optimized everything and how the raycasting should happen. So, using runservice.heartbeat, I carry out 6 raycasts to calculate a proper camera position, for pathfinding of the sound to the camera’s position. To my surprise, pathfinding is way less expensive than carrying out just 6 raycasts. I also need to carry out 3 more raycasts, less or more, per sound.
They take up to about a total of 30ms per second (Script Profiler: Average: 1s)… And I’ve already implemented a way to skip the heartbeat, if the last one took sooo long to process, to reduce lag. Is there any way to reduce raycast lag, other than parallelization? I’ve already quite parallelized it and I believe I’ll also have to make worker threads etc, but I want to improve the core performance of the raycasting itself. It’s just like any ordinary raycast code.
local function fixCameraPos(rayOrigin)
--print("Initial:", rayOrigin)
--Ypos
local rayDirection = Vector3.new(0, 3, 0).Unit * 3
local raycastParams = RaycastParams.new()
local newPos = rayOrigin
local raycastResult = workspace:Raycast(rayOrigin, rayDirection, raycastparams)
if raycastResult then
if raycastResult.Distance < 3 then
newPos = raycastResult.Position + Vector3.new(0,-0.01,0)
end
end
--Yneg
rayDirection = Vector3.new(0, -3, 0).Unit * 3
raycastResult = workspace:Raycast(newPos, rayDirection, raycastparams)
if raycastResult then
if not doNotEditY then
newPos = newPos - Vector3.new(0,raycastResult.Distance - 0.01,0)
end
end
--Xpos
rayDirection = Vector3.new(3, 0, 0).Unit * 3
raycastResult = workspace:Raycast(newPos, rayDirection, raycastparams)
if raycastResult then
if raycastResult.Distance < 1 then
newPos = newPos + Vector3.new(-1 + raycastResult.Distance/2,0,0)
end
end
--Xneg
rayDirection = Vector3.new(-3, 0, 0).Unit * 3
raycastResult = workspace:Raycast(newPos, rayDirection, raycastparams)
if raycastResult then
if raycastResult.Distance < 1 then
newPos = newPos + Vector3.new(1 - raycastResult.Distance/2,0,0)
end
end
--Zpos
rayDirection = Vector3.new(0, 0, 3).Unit * 3
raycastResult = workspace:Raycast(newPos, rayDirection, raycastparams)
if raycastResult then
if raycastResult.Distance < 1 then
newPos = newPos + Vector3.new(0,0,-1 + raycastResult.Distance/2)
end
end
--Zneg
rayDirection = Vector3.new(0, 0, -3).Unit * 3
raycastResult = workspace:Raycast(newPos, rayDirection, raycastparams)
if raycastResult then
if raycastResult.Distance < 1 then
newPos = newPos + Vector3.new(0,0,1 - raycastResult.Distance/2)
end
end
--print("Final:", newPos)
return newPos
end
--reverse raycast from end to start
for i=#waypoints, 1, -1 do
local waypoint = waypoints[i]
local distanceBtwnWaypointCamera = (waypoint.Position - workspace.Camera.CFrame.Position).magnitude
local rayOrigin = waypoint.Position
local rayDirection = (workspace.Camera.CFrame.Position - waypoint.Position).Unit * distanceBtwnWaypointCamera
local raycastResult = workspace:Raycast(rayOrigin, rayDirection, raycastparams)
if (not raycastResult) or (raycastResult.Distance <= distanceBtwnWaypointCamera) then
--cant see, the waypoint before this is last visible orb
skipCountAt = i+1
countedTurns = i+1
break
end
end
The fixCameraPosition function is really required so pathfinding doesn’t fail. And pathfinding takes about 2ms btw, in a whole one second
The reason I raycast from end to beginning of the waypoints is because, the last visible pathwaypoint will be closer to the end


