Need Help with Hostile having limited vision

Solo dev here. I am having trouble with setting up a hostile with low visibility. I have the code for the vision right here:

local npc = script.Parent
local visionCone = npc:WaitForChild("VisionCone")
local detectionRange = 30 -- Adjust the range as needed
local visionAngle = 45 -- Angle in degrees for field of view

local function isPlayerInVision(player)
    local character = player.Character
    if not character then return false end

    local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
    if not humanoidRootPart then return false end

    local npcPosition = npc.PrimaryPart.Position
    local playerPosition = humanoidRootPart.Position

    local directionToPlayer = (playerPosition - npcPosition).unit
    local npcFacingDirection = npc.PrimaryPart.CFrame.LookVector

    local dotProduct = directionToPlayer:Dot(npcFacingDirection)
    local angle = math.acos(dotProduct) * (180 / math.pi)

    if angle < visionAngle and (playerPosition - npcPosition).magnitude < detectionRange then
        return true
    end

    return false
end

local function onHeartbeat()
    for _, player in pairs(game:GetService("Players"):GetPlayers()) do
        if isPlayerInVision(player) then
            print(player.Name .. " is in vision!")
        end
    end
end

game:GetService("RunService").Heartbeat:Connect(onHeartbeat)

But I cannot seem to code to make the hostile walk to the player and fight them. I have been looking through the dev forum for hours and I cannot find anything. Thank you if you help!

2 Likes

Should try doing a print(angle, (playerPosition - npcPosition).magnitude) near the end of the function to see what it’s outputting.

2 Likes

It is outputting exactly what it is. Angle, Position, and NPC’s position. The vision isn’t the problem. I just cannot get the Hostile to walk to the player and do damage to it.

2 Likes

Nevermind, I had some help from a friend. Sorry for bothering you.

2 Likes

oh I see, when doing an AI like this I would recommend storing the hostiles current target in a variable. Then only looking for a new target when its target is invalid (such as checking Target:IsDescendantOf(workspace) and the likes).
In your onheartbeat function, if there’s a target then instead of looking for a new one, just using the MoveTo() method of the humanoid can be good for early prototyping.

Ex:

if (not Target) or (not isTargetValid(Target)) then
   -- find new target
end
if (not Target) then return end -- still don't have a target.

npc.Humanoid:MoveTo(Target.PrimaryPart.Position)
-- will cause the npc to move into the target, obviously would
-- want to refine further for your final product.
2 Likes

OH. This makes a little bit of sense. I’ll just try to edit my friends script. It’s scrappy lol.

2 Likes

This actually worked but of course I need it to fix it for my liking. Thanks so much!

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.