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)
