Line of sight issues

Hey! I was making an enemy for my RPG game. The enemy’s attack system is based off of magnitude. The only problem is that it will be spawned in a dungeon and I don’t want it to run into a wall trying to attack someone on the other side of it. Any advice on making a line of sight system?

1 Like

Have you even tried looking up any tutorials or anything?? if not, then do that first then come back to the forums.

I cant think of a way to type it into youtube

1 Like

Just type it how you want to the first time, if nothing shows up then search the devforums if you havent already?? i dont really know how you should type it either.

Look into raycasting, you can see if a part intersects with a line
You basically draw a line from the npc to the target, making sure to ignore any parts in the npc and target (so it doesnt detect itself or the target, only stuff blocking the line of sight path between the two), and see if somethings in the way

The basic starting point for something like this would be:

local params = RaycastParams.new()
params.FilterDescendantsInstances = {npc, target}
params.FilterType = Enum.RaycastFilterType.Blacklist
local result = workspace:Raycast(npc.HumanoidRootPart.Position, (target.HumanoidRootPart.Position-npc.HumanoidRootPart.Position), params)
if not result.Instance then
    --unobstructed
end
4 Likes

Probably the best way to do this would be using raycasting.

You would send a ray from your enemy to the character it is attacking. Then you see wether the ray hit anything. Keep in mind that the ray only sees the first object it hits, so it’s best to use collision groups and whitelists etc to make sure it won’t hit any other things that are ‘allowed’ to be in the way.

Good luck!

edit: oh @PapaBreadd was faster with a better answer :slight_smile:

2 Likes

I think the search you’re looking for is ‘path finding’

something like:

2 Likes
function IsInFov(src, dst, fov)
	fov = math.rad(math.clamp(fov, 0,  180))
	local srcToDst = (dst.Position - src.Position).Unit	
	local srcLook = src.CFrame.LookVector
	local dotProduct = srcToDst:Dot(srcLook)
	return dotProduct >= math.cos(fov/2)
end


function IsVisible(src, dst, blacklist)
	local params = RaycastParams.new()
	params.FilterDescendantsInstances = blacklist
	params.FilterType = Enum.RaycastFilterType.Blacklist
	local result = workspace:Raycast(src.Position, (dst.Position-src.Position), params)
	local Visible = true
	while true do
		if result then
			if result.Instance then
				table.insert(blacklist, result.Instance)
				params.FilterDescendantsInstances = blacklist
				if result.Instance.Transparency == 0 then Visible = false break end
				result = workspace:Raycast(result.Position, (dst.Position-result.Instance.Position), params)
				wait()
				continue
			else
				break
			end
		else
			break
		end
	end
	return Visible
end


game.Players.PlayerAdded:Connect(function(Player)
	Player.CharacterAdded:Connect(function(Character)
		local Head = Character:WaitForChild("Head")
		while true do
			local msg = "NOT IN FOV"
			if IsInFov(workspace.npcHead, Head, 90) then
				msg = "IN FOV"
				if IsVisible(workspace.npcHead, Head, {workspace.npcHead, Character}) then
					msg = msg.." || VISIBLE"
				end
			end
			print(msg)
			wait(0.1)
		end
	end)
end)

visiblity.rbxl (29.9 KB)

2 Likes