I’m trying to create a sort of compass type thing, that will point towards a part
local ClosestItem, ClosestItemDistance
for _, item in pairs(Items:GetChildren()) do
local Distance = (item.Position - Character.HumanoidRootPart.Position).Magnitude
if Distance <= MaximumDistance then -- Within range
if ClosestItem then -- Already a closest item, check if closer
if Distance < ClosestItemDistance then
ClosestItem = item
ClosestItemDistance = Distance
end
else
ClosestItem = item
ClosestItemDistance = Distance
end
end
end
if not ClosestItem then return end
-- Work out CFrame
local pos = Camera.CFrame.Position - ClosestItem.Position
local rot = -math.deg(math.atan2(pos.X, pos.Z)) + 90
if rot < 0 then
rot += 360
end
Tracker.Rotation = rot
However if this red part is the part I’m looking for, it doesn’t properly match. The way to tell which way the pointer is pointing is the square at the top.
The black frame is whats in studio (Tracker) while the red arrow is to show where the black should be point
Check out WorldToScreenPoint. It will return coordinates on the screen, you can then use those coordinates as a Vector2 to calculate the rotation to make for the UI element.
To calculate the rotation (vec2 being your WorldToScreenPoint, vec1 being your current compass position):
You may not be using the correct position for the compass. This is what I have done taking from the WorldToScreenPoint article’s code and applying the formula. I’ve added + 90 as it appears there was an offset.
local camera = workspace.CurrentCamera
local vector, onScreen = camera:WorldToScreenPoint(workspace.Part.Position)
local screenPoint = Vector2.new(vector.X, vector.Y)
local frame = game.Players.LocalPlayer.PlayerGui.ScreenGui.Frame
frame.Rotation = math.deg(math.atan2(screenPoint.Y - frame.AbsolutePosition.Y, screenPoint.X - frame.AbsolutePosition.X)) + 90
How can I get it so the top of the frame is always what’s pointing, and not just rotating, as the arrow is at the top of the frame, but gets flipped to be at the bottom?