Hello, my goal is self-explanatory, have a Ui arrow point in the direction of a part that is in the workspace.

The issue is that I cannot figure out how to make the Ui arrow move freely on the Frame, it sticks to the side of the Frame, making it look "janky" by constantly teleporting around the Frame from side to side.

Here is a video example of what I am trying to achieve and what I have so far.

imgur.com/a/MmHyoe4 https://imgur.com/a/MmHyoe4

And here is the LocalScript which makes my version work like it does.

local Markers = {}
local Screen = script.Parent.Holder.AbsoluteSize
local T = game:GetService("TweenService")

for i,v in pairs(game.ReplicatedStorage.Markers:GetChildren()) do
	local Marker = script.Sample:Clone()
	Marker.Parent = script.Parent.Holder
	Marker.ImageColor3 = v.Config.MarkerColor.Value
	Marker.RotateLabel.Arrow.ImageColor3 = v.Config.MarkerColor.Value
	Marker.Icon.Image = v.Config.Icon.Value
	table.insert(Markers,{Marker,v})
end

function ClampMarkerToBorder(X,Y,Absolute)
	X = Screen.X - X
	Y = Screen.Y - Y
	
	local DistanceToXBorder = math.min(X,Screen.X-X)
	local DistanceToYBorder = math.min(Y,Screen.Y-Y)
	
	if DistanceToYBorder < DistanceToXBorder then 
		if Y < (Screen.Y-Y) then
			return math.clamp(X,0,Screen.X-Absolute.X),0
		else
			return math.clamp(X,0,Screen.X-Absolute.X),Screen.Y - Absolute.Y
		end
	else
		if X < (Screen.X-X) then
			return 0,math.clamp(Y,0,Screen.Y-Absolute.Y)
		else
			return Screen.X - Absolute.X,math.clamp(Y,0,Screen.Y-Absolute.Y)
		end
	end
end

game:GetService("RunService").Heartbeat:Connect(function()
	for i,Stat in pairs(Markers) do
		local Marker = Stat[1]
		local Location = Stat[2]
		Marker.Visible = Location.Config.Enabled.Value
		
		if Location.Config.Enabled.Value then
			local MarkerPosition , MarkerVisible = game.Workspace.CurrentCamera:WorldToScreenPoint(Location.Position)
			local MarkerRotation = game.Workspace.CurrentCamera.CFrame:Inverse()*Location.CFrame
			local MarkerAbsolute = Marker.AbsoluteSize
			
			local MarkerPositionX = MarkerPosition.X - MarkerAbsolute.X/2
			local MarkerPositionY = MarkerPosition.Y - MarkerAbsolute.Y/2
			
			if MarkerPosition.Z < 0  then
				MarkerPositionX,MarkerPositionY = ClampMarkerToBorder(MarkerPositionX,MarkerPositionY,MarkerAbsolute)
			else
				if MarkerPositionX < 0 then
					MarkerPositionX = 0
				elseif MarkerPositionX > (Screen.X - MarkerAbsolute.X) then
					MarkerPositionX = Screen.X - MarkerAbsolute.X
				end
				if MarkerPositionY < 0 then
					MarkerPositionY = 0
				elseif MarkerPositionY > (Screen.Y - MarkerAbsolute.Y) then
					MarkerPositionY = Screen.Y - MarkerAbsolute.Y
				end
			end
				
			Marker.RotateLabel.Visible = not MarkerVisible
			Marker.Visible = not MarkerVisible
			Marker.RotateLabel.Rotation = 90 + math.deg(math.atan2(MarkerRotation.Z,MarkerRotation.X))
			Marker.Position = UDim2.new(0,MarkerPositionX,0,MarkerPositionY)
			
			T:Create(Marker,TweenInfo.new(.5),{ImageColor3 = Location.Config.MarkerColor.Value}):Play()
			T:Create(Marker.RotateLabel.Arrow,TweenInfo.new(.5),{ImageColor3 = Location.Config.MarkerColor.Value}):Play()
			local CurrentTime = tick()
			if Location.Config.BurstType.Value == "Normal" then
				if math.floor((CurrentTime%1.5)*100)/100 <= .01 then
					local Burst = script.BurstRings:Clone()
					Burst.ImageColor3 = Location.Config.MarkerColor.Value
					Burst.Parent = Marker
					T:Create(Burst,TweenInfo.new(1),{Size = UDim2.new(2,0,2,0),ImageTransparency = 1}):Play()
					game.Debris:AddItem(Burst,1)
				end
			elseif Location.Config.BurstType.Value == "Police" then
				if math.floor((CurrentTime%1.5)*100)/100 <= .01 then
					warn("Blue")
					local Burst = script.BurstRings:Clone()
					Burst.ImageColor3 = Color3.fromRGB(82,124,174)
					Burst.Parent = Marker
					T:Create(Burst,TweenInfo.new(1),{Size = UDim2.new(2,0,2,0),ImageTransparency = 1}):Play()
					game.Debris:AddItem(Burst,1)
				elseif math.floor((CurrentTime%.75)*100)/100 <= .01 then
					warn("Red")
					local Burst = script.BurstRings:Clone()
					Burst.ImageColor3 = Color3.fromRGB(255,89,89)
					Burst.Parent = Marker
					T:Create(Burst,TweenInfo.new(1),{Size = UDim2.new(2,0,2,0),ImageTransparency = 1}):Play()
					game.Debris:AddItem(Burst,1)
				end
			end
		end
	end
end)