People say I should use camera:WorldToScreenPoint, but I they still return when its in the screen and blocked completely by another part, i thought i should do raycasting but it only returns true when Im looking directly at it, imagine a part in your top left corner of the screen, i want it to load but i have to look directly to it
i want it to load when its in my screen and i can SEE it
local cloned_block = block:Clone()
local camera = workspace.CurrentCamera
local vector, onScreen = camera:WorldToScreenPoint(cloned_block.Position)
if onScreen then
local ray = Ray.new(game:GetService("Players").LocalPlayer.Character.Head.Position,cloned_block.Position)
local hit = workspace:FindPartOnRayWithIgnoreList(ray,game:GetService("Players").LocalPlayer.Character:GetDescendants())
if hit then
cloned_block.CFrame = CFrame.new(x*grid,y*grid,z*grid)
cloned_block.Parent = workspace.terrain
end
end
local cloned_block = block:Clone()
local camera = workspace.CurrentCamera
local partToCheck = cloned_block
local vector, inViewport = camera:WorldToViewportPoint(partToCheck.Position)
local onScreen = inViewport and vector.Z > 0
local ray = camera:ViewportPointToRay(vector.X, vector.Y, 0)
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
raycastParams.FilterDescendantsInstances = {partToCheck, game.Players.LocalPlayer.Character}
local raycastResult = workspace:Raycast(ray.Origin, ray.Direction * 1000, raycastParams)
local isVisible = onScreen and not raycastResult
if isVisible then
cloned_block.CFrame = CFrame.new(x*grid,y*grid,z*grid)
cloned_block.Parent = workspace.terrain
end
local _, OnScreen = workspace.CurrentCamera:WorldToScreenPoint(ObjectPosition)
if OnScreen then
if #workspace.CurrentCamera:GetPartsObscuringTarget({workspace.CurrentCamera.CFrame.Position,Object.Position},{Object}) == 0 then
-- its on screen and its not obstructed
end
end
local Part = workspace.Look -- This is the part I want this script to check if is visible
local Camera = workspace.Camera
local Character = game:GetService('Players').LocalPlayer.Character
local RunService = game:GetService('RunService')
local Parameters = RaycastParams.new()
Parameters.FilterDescendantsInstances = {Character, Part}
Parameters.FilterType = Enum.RaycastFilterType.Blacklist
RunService.RenderStepped:Connect(function()
local Vector, OnScreen = Camera:WorldToViewportPoint(Part.Position)
if OnScreen then
if workspace:Raycast(Camera.CFrame.Position, Part.Position - Camera.CFrame.Position, Parameters) == nil then
warn('Part is Onscreen')
end
end
end)
The downside to this method is that it will detect transparent parts (but maybe you would want that). I can not compare my script with FartFella’s because his script would not work. Although this method does detect transparent parts, I believe it still may be better because you can have a for loop loop through the workspace and add any parts that have a targeted transparency. (For example, I may use a for loop to make the ray not detect any parts that have a transparency more than 0.5.)
By the way, Ray.new is old so I suggest you to learn the newer more accurate/faster workspace:Raycast( )
llocal function IsObjectVisible(Object: BasePart)
local ObjectPosition = Object.Position
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Camera = workspace.CurrentCamera
local Character = Player.Character
local CameraPosition = Camera.CFrame.Position
local Position = (CameraPosition + ObjectPosition) * 0.5
local Diff = (CameraPosition - ObjectPosition)
local _, OnScreen = Camera:WorldToScreenPoint(ObjectPosition)
local Params = OverlapParams.new()
Params.FilterDescendantsInstances = {Character, Object}
local BoundBox = workspace:GetPartBoundsInBox(CFrame.new(Position, Position + Diff.Unit), Vector3.zAxis * Diff.Magnitude, Params)
return OnScreen and #BoundBox == 0
end
Edit1: Oops give me a second found a bug
Edit2: Fixed