Raycasts take extremely long, despite being short & low in amount

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



I’ve tried these solutions:

  • I placed BruteForceAllSlow = false in the raycastparams

  • The ray length is always what I want it to be (I do .Unit() to the directional vector, then multiply it by how many studs the ray’s length should be)

  • Map isn’t densely populated and doesn’t have alot of parts, even when my character is standing in a simple room the raycasts take reaaallly long

  • Already using a blacklist to exclude many things such as the sound’s part, and my character

I’ve also tried with the new camera function which is Camera:GetPartsObscuringTarget(). Yields the same results, which is good, but it’s just as slow as the raycasting (although it’s said to be somewhat faster, in the documentation). It also has the ignoreList, so it will ignore my character as well

  • The time measuring is via roblox’s Script Profiler, in the developer tab, so I believe it’s accurate to some extent

  • This is tested in game mode, not studio mode. So there should be no weird bugs occuring

Though I have a small question:
Is raycasting slow on ROBLOX on Android? Haven’t really tested this with the PC because I’m using a substitute, old PC for now (although my friends who have tried the game, also get bad CPU time… so it’s quite possible it’s slow on both…)