I'm looking to make a stealth-based AI for a game that some friends and I are working on, although I don't know what to do for the monster's vision. My ideas so far have been:
Raycasting, I came up with this idea before I really knew what it was and realized I would have to do hundreds and hundreds of raycastings per second to cover the entire "FOV" of the monsters.
Welding cones made of corner bricks to the monster's face, problem with this is that the cone would make the monster turn slow.
Using a script to position cones from the above idea in-front of the monster's head, simulating a line of sight, while allowing the monster faster turning.
I've actually made a script that does this, you can use it if you want.
local fov = 90 -- This is the monsters field of view local dist = 50 -- This is the monsters view distance local monster = script.Parent.Parent.Character.Head -- Change this to the monsters position function MakeRay(startPos, endPos, show) -- Creates a new ray local ray = Ray.new(startPos, endPos) local obj, endPoint = Workspace:FindPartOnRay(ray) if show then -- This is for debugging. It will make the rays visible local rayPart = Instance.new("Part", Workspace) rayPart.Name = "RayPart" rayPart.BrickColor = BrickColor.new("Bright red") rayPart.Transparency = 0.5 rayPart.Anchored = true rayPart.CanCollide = false rayPart.TopSurface = Enum.SurfaceType.Smooth rayPart.BottomSurface = Enum.SurfaceType.Smooth rayPart.formFactor = Enum.FormFactor.Custom rayPart.Size = Vector3.new(0.2, 0.2, dist) rayPart.CFrame = CFrame.new(startPos, Vector3.new(endPos.x,1.5,endPos.z)) * CFrame.new(0, 0, -dist/2) game.Debris:AddItem(rayPart, 0.1) -- Add the part to Debris so it will remove itself after 0.1 second end return obj -- Return any found objects with ray end while true do local start = -180-(fov/2) -- Give the ray the right lookVector for t = start, start+fov, 5 do -- You can change the 5 to another number as long as it's dividable by the fov. This represents the distance between each endPoint of the ray. local target = monster.CFrame -- Set the target to yourself * CFrame.new(dist*math.sin(math.rad(t)), monster.Position.Y, dist*math.cos(math.rad(t))) -- Add the radians * monster.CFrame.lookVector -- Get the lookVector of the monster local hit = MakeRay(monster.CFrame.p, target, true) -- Create a new ray. Set the last value to false if you're done debugging. if hit then -- If the ray has a hit if hit.Parent:FindFirstChild("Humanoid") then -- If the hit is a humanoid print("Humanoid in sight") end end end game:GetService("RunService").RenderStepped:wait() end