Hello, thank you for assisting me in my troubles. In my local script located in StarterCharacterScripts, I have this custom camera system that shows an indicator of an NPC or player when their avatar goes off the local player’s screen. The only catch is that when the non-local player goes under the local player’s viewpoint and walks a certain distance, their indicator will gradually rise for some odd reason.
I’d appreciate it if you could help me as I spent a lot of time working on this script, only for it to not turn out the way that I liked it.
Script:
local function updateIndicators()
for target, indicator in pairs(indicators) do
local character = target:IsA("Player") and target.Character or target
local hrp = character and character:FindFirstChild("HumanoidRootPart")
if not hrp then
indicator.Visible = false
continue
end
local viewportSize = cam.ViewportSize
local screenCenter = Vector2.new(viewportSize.X / 2, viewportSize.Y / 2)
local screenPoint, onScreen = cam:WorldToViewportPoint(hrp.Position)
-- If the target is on screen and in front of the camera, hide the indicator
if onScreen and screenPoint.Z > 0 then
indicator.Visible = false
continue
end
-- Calculate the distance from the local player to the target player
local distanceFromPlayer = (player.Character.HumanoidRootPart.Position - hrp.Position).Magnitude
-- Smoothly raise the indicator's position if the target is too far away
local moveThreshold = 100 -- Adjusted this threshold as needed
local upwardOffset = 0
if distanceFromPlayer > moveThreshold then
upwardOffset = math.min((distanceFromPlayer - moveThreshold) / 0.5, 0) -- Clamped upwardOffset
end
local toTarget = (hrp.Position - cam.CFrame.Position).Unit
local forward = cam.CFrame.LookVector
local dotProduct = forward:Dot(toTarget)
if dotProduct < 0 then
screenPoint = Vector3.new(-screenPoint.X, -screenPoint.Y, 0)
end
local direction = (Vector2.new(screenPoint.X, screenPoint.Y) - screenCenter).Unit
local edgeOffset = 50 -- Adjusted for better visual appearance
local maxX, maxY = viewportSize.X - edgeOffset, viewportSize.Y - edgeOffset
local slope = direction.Y / direction.X
local edgeX, edgeY = screenCenter.X, screenCenter.Y
if math.abs(slope) > viewportSize.Y / viewportSize.X then
edgeY = direction.Y > 0 and maxY or edgeOffset
edgeX = screenCenter.X + (edgeY - screenCenter.Y) / slope
else
edgeX = direction.X > 0 and maxX or edgeOffset
edgeY = screenCenter.Y + (edgeX - screenCenter.X) * slope
end
edgeX = math.clamp(edgeX, edgeOffset, maxX)
edgeY = math.clamp(edgeY + upwardOffset, edgeOffset, maxY) -- Adjust Y position with upwardOffset
local tweenInfo = TweenInfo.new(0.15, Enum.EasingStyle.Linear, Enum.EasingDirection.Out)
local tween = tweenService:Create(indicator, tweenInfo, {Position = UDim2.new(0, edgeX, 0, edgeY)})
tween:Play()
indicator.Rotation = math.deg(math.atan2(direction.Y, direction.X)) + 90
indicator.Visible = true
end
end