How do I make a UI point to an object?

So, I’ve been trying to implement the features of waypoints by using a compass UI that will N,E,S, & W, along with the waypoints. I managed to make it where the N,E,S, & W labels work but I haven’t been able to find a solution to getting a waypoint to point where the waypoint is at. I also want it to constantly point at where the waypoint is at when the player’s position moves.

Here is the script for the compass UI.

local smoothness = 30/3

wait(1)

local player = game.Players.LocalPlayer
local camera = workspace.CurrentCamera

local dev = script.Parent

local lastY = 0
local units = {
	[dev.N ] = -math.pi * 4/4;
	[dev.NE] = -math.pi * 3/4;
	[dev.E ] = -math.pi * 2/4;
	[dev.SE] = -math.pi * 1/4;
	[dev.S ] =  math.pi * 0/4;
	[dev.SW] =  math.pi * 1/4;
	[dev.W ] =  math.pi * 2/4;
	[dev.NW] =  math.pi * 3/4;
	[dev.Frame] = math.pi * game.Workspace.Furnace.PromptPart.Position.X/game.Workspace.Furnace.PromptPart.Position.Y;
}

local Waypoints = {
	[dev.Frame] = math.pi * game.Workspace.Furnace.PromptPart.Position.X/game.Workspace.Furnace.PromptPart.Position.Y;
}

function restrictAngle(angle)
	if angle < -math.pi then
		return angle + math.pi*2
	elseif angle > math.pi then
		return angle - math.pi*2
	else
		return angle
	end
end

while true do
	local delta = wait(1/30)
	
	local look = camera.CoordinateFrame.lookVector
	local look = Vector3.new(look.x, 0, look.z).Unit
	local lookY = math.atan2(look.z, look.x)
	
	local difY = restrictAngle(lookY - lastY)
	lookY = restrictAngle(lastY + difY*delta*smoothness)
	lastY = lookY
	
	for unit, rot in pairs(units) do
		rot = restrictAngle(lookY - rot)
		if math.sin(rot) > 0 then
			local cosRot = math.cos(rot)
			local cosRot2 = cosRot*cosRot
			
			unit.Visible = true
			unit.Position = UDim2.new(0.5 + cosRot*0.6, unit.Position.X.Offset, 0.5, 0)
		else
			unit.Visible = false
		end
	end
end

Here’s the where the script is located.
image

If needed I will elaborate further on what I want to try to achieve. Any help will be appreciated!

1 Like

simple math

local ui = script.Parent --the compass
local wp = workspace:WaitForChild('waypoint') --a part representing the waypoint

game:GetService('RunService').RenderStepped:Connect(function()
	local cam: Camera? = workspace.CurrentCamera
	if cam then
		local camCf: CFrame = cam.CFrame
		local cf: CFrame = CFrame.lookAt(camCf.Position, wp.CFrame.Position) --this CFrame is looking at the waypoint
		local _, selfAngle: number = camCf:ToOrientation() --measure the angle of the camera itself
		local _, relAngle: number = cf:ToOrientation() --measure the absolute angle of the CFrame looking at the waypoint
		local angle: number = math.deg(selfAngle - relAngle) --offset the angle
		
		ui.Rotation = angle
	end
end)

4 Likes

I see, ill try implement this into my code, obviously ill need tweak abit.

1 Like

So i’ve tried my best into researching alternatives and even tried to much your code along with mine but I’ve only kept hitting roadblock after roadblock. I’ll to give a video demonstration of what i’m trying to achieve.

I wish to try making it where a small icon will appear on the compass ui in the top center of the player’s screen will show where the waypoint is.

Get the part’s X world position in the camera, you can define when it’s out of bounds with math.clamp and other sorts of math to determine where it fits on the GUI.

And obviously, if the part is at the X-Center of the screen, it’ll be in the middle of the GUI, 0.5. There’s some Part CFrame to Camera functions embedded to help you with this.

  • Using math.clamp helps you determine to hide the waypoint if it’s out of the X-axis view.