The Power of EQS and Using EQS to Find Cover Points From Target

For those who know what EQS is:
EQS(Enviroment query system) is an algorithm that surrounds the queried pawn with points(vector3s) and give these points a score for its desired behaviour. EQS is a powerful tool that for some reason a lot of ROBLOX developers dont mention here in the forums.
with EQS you can customize the grid shape/ difference between the points, 3d grid, and so on.

There are a lot of forms to set up your EQS search, like circle, cube, grid, cone and more, but in this tutorial i will set it up as a simple 2d grid. it should visually look like that:

Now in order to use EQS to find a good place for out pawn to hide in roblox we should loop through the x and z axis to create a simple grid around our queried pawn in ROBLOX.

then we discard all the points whose are not fitting in the grid, the ones whose inside a part and/or have direct sight to the target.

we have to use these two

local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Include
raycastParams.FilterDescendantsInstances = {workspace.Map}
local oOverlapParams = OverlapParams.new()
oOverlapParams.FilterDescendantsInstances = {workspace.Map}
oOverlapParams.FilterType = Enum.RaycastFilterType.Include

Now create a function that would call the points by the x and z offset from the target.

function getCoverPointFrom(pos : Vector3)
	local points = {}
	local mh = math.huge
	local desiredPoint = nil
	for x= -20,20,4 do
		for z= -20,20,4 do
			local ray = workspace:Raycast(script.Parent.Position+ Vector3.new(x,script.Parent.Position.Y,z), pos-(script.Parent.Position+ Vector3.new(x,script.Parent.Position.Y,z)),raycastParams)

			local isInPart = #workspace:getPartBoundsInRadius(script.Parent.Position+ Vector3.new(x,script.Parent.Position.Y,z), 1.5, oOverlapParams) > 0
			if isInPart == false and ray and ray.Instance then
				points[script.Parent.Position+ Vector3.new(x,script.Parent.Position.Y,z)] =  (pos-script.Parent.Position-Vector3.new(x,script.Parent.Position.Y,z)).Magnitude
				
				if mh > points[script.Parent.Position+ Vector3.new(x,script.Parent.Position.Y,z)] then
					mh = points[script.Parent.Position+ Vector3.new(x,script.Parent.Position.Y,z)]
					desiredPoint = script.Parent.Position+ Vector3.new(x,script.Parent.Position.Y,z)
				end
			end

		end
	end
	return desiredPoint
end

Here is a place to try:
eqs.rbxl (54.3 KB)

1 Like