I'm working on a part that does something when you look at it, I'm not exactly sure what I can do and I don't think lookVector
would work, but I don't know much about it, I've been doing some research and I haven't found anything helpful, most of the things I found were too vague, or didn't seem like they would work. Any help would be nice, thanks in advance!
You can get the screen position of a 3D point with the WorldToScreenPoint method of the camera.
local screenPoint, isVisible = camera:WorldToScreenPoint(object.Position)
This however doesn't take the size of the object into account. What you can do is take all the corners of the object and see if any of them are on the screen. Here's an example on how this can be implemented:
local localPlayer = game.Players.LocalPlayer local camera = workspace.CurrentCamera local part = workspace.Part local GUI = Instance.new("ScreenGui", localPlayer.PlayerGui) local function drawFrame(topLeft, bottomRight) local size = bottomRight - topLeft local frame = Instance.new("Frame") frame.Position = UDim2.new(0, topLeft.X - size.X/2, 0, topLeft.Y - size.Y/2) frame.Size = UDim2.new(0, size.X, 0, size.Y) frame.BackgroundTransparency = 0.2 frame.BackgroundColor3 = BrickColor.Red().Color frame.Parent = GUI game:GetService("Debris"):AddItem(frame, 1/30) end local function isPartVisible(obj) local center = obj.Position -- No need to do any extra calculations if the center point is on the screen local centerPoint, centerVisible = camera:WorldToScreenPoint(center) if centerVisible then return true, centerPoint end local extents = obj.Size/2 local extentPoints = { [1] = (Vector3.new(center.X + extents.X, center.Y + extents.Y, center.Z + extents.Z)), [2] = (Vector3.new(center.X - extents.X, center.Y - extents.Y, center.Z - extents.Z)), [3] = (Vector3.new(center.X - extents.X, center.Y + extents.Y, center.Z + extents.Z)), [4] = (Vector3.new(center.X + extents.X, center.Y - extents.Y, center.Z + extents.Z)), [5] = (Vector3.new(center.X + extents.X, center.Y + extents.Y, center.Z - extents.Z)), [6] = (Vector3.new(center.X - extents.X, center.Y - extents.Y, center.Z + extents.Z)), [7] = (Vector3.new(center.X + extents.X, center.Y - extents.Y, center.Z - extents.Z)), [8] = (Vector3.new(center.X - extents.X, center.Y + extents.Y, center.Z - extents.Z)), } for n = 1, #extentPoints do local point = extentPoints[n] local screenPoint, isVisible = camera:WorldToScreenPoint(point) drawFrame(screenPoint, screenPoint + Vector3.new(10, 10)) if isVisible then return true, screenPoint end end return false end game:GetService("RunService").Heartbeat:Connect(function() print(isPartVisible(part)) end)
edit: Of course it is possible that the object is on the screen without any of the 9 points being visible. The final method depends on what kind of requirements you have.
The WorldToScreenPoint method returns information about where on the screen a Vector3 is, but also whether or not it's visible.
This seems to be pretty much exactly what you're looking for, with the caveat that it only returns true if the precise Vector3 is visible. If You've got a large object, you might be able to see the edge of it before its .Position is visible on screen.
If you throw a brick into the workspace called "CanYouSeeMe", then the following should, when you click and hold, take away your health whenever you can see it, and give it back to you when you can't.
script.Parent.Equipped:Connect(function(m) held = false m.Button1Down:Connect(function() local player = game:GetService("Players").LocalPlayer local cam = workspace.CurrentCamera local fov = math.rad(workspace.CurrentCamera.FieldOfView) local mouse = player:GetMouse() local character = player.Character held = true while held and wait() do local locationAndDepth, visible = cam:WorldToScreenPoint(workspace.CanYouSeeMe.Position) if visible then character.Humanoid:TakeDamage(1) else character.Humanoid.Health = character.Humanoid.Health + 1 end end end) m.Button1Up:Connect(function() held = false end) script.Parent.Unequipped:Connect(function() held = false end) end)