Answered by
6 years ago Edited 6 years ago
What you want is WorldToScreenPoint, which I wrote a little bit about here.
This can be used to return whether or not a part is visible on screen.
However, this doesn't take in to account parts that might be in the way - to solve this problem we can use GetPartsObscuringTarget.
Then finally, we want to run this locally on ever rendered frame, so we can use RenderStepped. Since this is running locally, it shouldn't place undue load on the server.
I wrote a little babby example - just put a brick in the workspace called "CanYouSeeMe", and put the code in a LocalScript in StarterPlayer.StarterPlayerScripts.
01 | local seenPreviously = false |
02 | player = game:GetService( "Players" ).LocalPlayer |
05 | local s = Instance.new( "SelectionBox" ) |
06 | s.Adornee = player.Character |
07 | s.Parent = player.Character |
10 | conn = game:GetService( "RunService" ).RenderStepped:Connect( function (t) |
11 | if not seenPreviously then |
12 | local target = workspace.CanYouSeeMe |
13 | local camera = workspace.CurrentCamera |
14 | local locationAndDepth, visible = camera:WorldToScreenPoint(target.Position) |
17 | local obscuring = camera:GetPartsObscuringTarget( { target.Position } , { target } ) |
18 | if #obscuring > 0 then |
23 | partSeen(workspace.CanYouSeeMe) |
Using both conn:Disconnect()
and seenPreviously
is doing the same thing twice, but one might be easier to use than the other depending on what you're doing.