How to do the maths behind raycasting a FOV?

image

Working on a neural network game and I am working on censes for the instances. First cense: Vision is generated by raycasts. Pray have FOV of 130 and preditors have a FOV of 50.

How would I go with raycasting every 5 degrees of the FOV? I’m not the best at math behind this.

Here’s a snippet of my script:

for c=1, rRange do
						local optimalangle = Vector3.new(0,entity.part.Orientation.Y,0) + Vector3.new(0,-(r/2)+(r*(c/rRange)),0)
						
				local optimalorigin = entity.part.Position + entity.part.CFrame.LookVector*(entity.part.Size.Z/2)
				local params = RaycastParams.new() params.FilterType = Enum.RaycastFilterType.Whitelist
						local ignore = {entity.part}
				if entity.entity == 'pray' then
					ignore[2] = preditorFolder
				else
					ignore[2] = prayFolder
				end
				params.FilterDescendantsInstances = ignore
				local newray = workspace:Raycast(optimalorigin,optimalangle,params)
				if newray then
							if newray.Distance <= 5 then
                              -- Proccessing is here
					end
				end


			end
local r = 50 if entity.entity == 'pray' then r = 130 end
					local rRange = r/5

Just to be clear, you can’t do a “ray cast” that’s actually in the shape of a continous arc, only approximate it with a couple of individual “normal” ray casts.

How to do that in code depends on how exactly you want your creatures’ senses to work. You’ve drawn the circular arc coming out of one face of a part, but what should happen if the creature ends up a bit rotated around it’s own Z axis? Should the arc still be “flat” in the world’s X/Z axes or should it follow the creature’s rotation?

Uhh I tried drawing it but it’s no easy xD

Here’s an example of how rays can be cast in a circular arc:

function arcRayCast(origin, spreadAngle, maxRadius, numSegments, raycastParams)
    local angleStep = spreadAngle/numSegments
    local firstCFrame = origin * CFrame.Angles(0, -spreadAngle/2, 0)
    local results = {}
    for angle = -spreadAngle/2, spreadAngle/2, angleStep do
        local rayCFrame = firstCFrame * CFrame.Angles(0, angle, 0)
        local rayResult = game.Workspace:Raycast(rayCFrame.Position, rayCFrame.LookVector * maxRadius, raycastParams)
        if not result then continue end
        table.insert(results, rayResult)
    end
    
    return results
end

I think it’s right but I can’t test it ATM

3 Likes

Very sorry for the almost year late reply :sweat_smile:, but thanks! Even though the project in question I’ve ended months ago your help is still useful!