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?
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
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
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
I think the search you’re looking for is ‘path finding’
something like:
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)