Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

[ ADVANCED ] GUI arrow won't follow a part in workspace?

Asked by
14dark14 167
1 year ago
Edited 1 year ago

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)

Answer this question