ents.FindInCone for player detection issues.

Hello, so I’ve been trying to figure out an effective way to code a way to detect whether or not players can see you on their screen while using a SWEP. For example: If you are detected by at least one player I’m trying to make it to where a panel will popup to alert the you that you are seen. As soon as the player turns away the panel should automatically go away (implying a think or paint hook.) One way I’ve attempted with some success is using the ents.FindInCone() command at every player on the server’s positions using their GetForward to set the cone in front of them for 3000 gmod units. Not sure how the angle plays into it, however, when I set it to anything other than 0 it doesn’t work.

The method I attempted is below, however, does not succeed 100% of the time when tested on bots. Sometimes it will show the HUD when the bot is looking away from the player and, after changing nothing, the HUD will be shown when the bot is looking at the player instead.

File: weapon_example.lua in lua/weapons folder




--fancy SWEP stuff up here

hook.Add( "HUDPaint", "HUDDisplay", function()   

local ply = LocalPlayer()

if( !ply:HasWeapon( "weapon_example" ) ) then return end

--Create the HUD if it doesn't exist
if( !IsValid( HudPanel ) ) then
	HudPanel = vgui.Create( "CUSTOMHUD" )
	HudPanel:Hide()  --Assumes no one sees you upon creation
end

--Initialize isFacing
local isFacing = false

--Check every player's forward position in a cone for you
for k, pl in pairs( player.GetAll() ) do
	for k,ent in pairs( ents.FindInCone( pl:GetPos(), pl:GetForward(), 3000, 0 ) ) do
		if( ent == ply && pl != ply ) then
			isFacing = true	
			break    --Exit inner loop if entry found else check another player's forward position
		end
	end
        if( isFacing ) then break end     ---Exit outer loop if entry is found within inner loop
end

if( IsValid( HudPanel ) && isFacing ) then
	HudPanel:Show()   --You are seen!
else
	HudPanel:Hide()    --You are hidden!  //Note: I've tried Remove() with no success either.
end

end )


Is there a better way to do this? I’ve thought about trying Entity:TestPVS Serverside, however, am very unfamiliar with it as the gmod wiki does not do a good job in explaining it properly. Also this would bring about the issue of networking it from server to client which I’ve tried with net.Send() and failed horribly at. Even using ply:SetNWBool() gave major issues when communicating from server to client on this specific matter.

Note/Update: Serverside the SWEP works perfectly. This is only messing up on client side in regards to displaying the HUDPanel. The HUDPanel will only show and hide upon pressing the PrimaryAttack button rather than update every frame with HUDPaint.

Unfortunately ent:IsLineOfSightClear() doesn’t consider if the player is actually looking at you. You can be facing the opposite direction and still have line of sight with a player. This function checks if there is a world object ( a wall ) between you and the ent/vector being tested.

Tried playing around with the radius of your cone?

Edit: Ignore me, im thinking odd today XD

You can use a serversided ply:Visible(pl) in a loop, and if that returns true, then there is no wall or anything blocking you and he can see you. Now check if he’s looking in your direction by taking the dot product of his aim vector to the normalized vector between you and him, and if that is over a certain number, he’s looking in your direction. That number could be 0.7, 0.8 etc, experiment with it.

My apology for the delay. Thank you for the help! Everything works perfectly - genius approach.