WorldToScreenPoint Alternative

I want to detect when a player looks at an NPC.

The function WorldToScreenPoint works and returns true if the player looks at the NPC and returns false if they are not looking at it. However, it does not take into account the 3D workspace. In other words, if I made the NPC and player look at each other but put a wall between the NPC and the player, it will return true even though the wall is blocking their sight.

Therefore, I would like to know if there are any other methods or functions that can achieve the same thing WorldToScreenPoint does but also pay attention to if something in the Workspace blocks the view.

Raycasting!
You can use Camera:WorldToViewportPoint and then Camera:ViewportPointToRay. Use the resulting Ray object to raycast.

local vector, inViewport = Camera:WorldToViewportPoint(point)

if inViewport then
    local ray = Camera:ViewportPointToRay(vector.X, vector.Y)
    local result = workspace:Raycast(ray.Origin, ray.Direction * maxDistance)
    
    if result and result.Instance:IsDescendantOf(npc) then
        -- The player can see the NPC!
    end
end

See Camera:WorldToViewportPoint, Camera:ViewportPointToRay, WorldRoot:Raycast, Instance:IsDescendantOf

Whats maxDistance? Its giving a red line under maxDistance within the script and when I run it, I get this error: attempt to perform arithmetic (mul) on Vector3 and nil

Like with any of my examples, I do not expect people to copy and paste my code. Rather, you should attempt to understand it.
maxDistance is the max distance.

1 Like