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)