Need help with my gui effects!

I’m trying to make a ui effect like the game called “Watch dogs 2” (gave an image reference below) need the line to be starting from right on top my menu and it should end on a part that i chose here.
Can anyone show a better way?

This is how it looks like:


This is how it should look like:



Here’s my script:

local RS = game:GetService("RunService")
local TS = game:GetService("TweenService")

game.Workspace:WaitForChild("Part")

local function DivideSmaller(X, Y)
    return math.atan2(Y, X) * 180 / math.pi
end

local Frame = Instance.new("Frame")

local F1 = script.Parent.ImageLabel
local FakeFrame = Instance.new("Frame")
Frame.Size = UDim2.new(0,0,0,0)
Frame.Parent = script.Parent
spawn(function()
    RS.RenderStepped:Connect(function()
        local pospos = game.Workspace.CurrentCamera:WorldToScreenPoint(game.Workspace.Part.Position)
        Frame.Position = UDim2.fromOffset(pospos.X,pospos.Y)
    end)
end)

local F2 = Frame

RS.RenderStepped:Connect(function()
    local XLength = F1.AbsolutePosition.X - F2.AbsolutePosition.X
    local YLength = F1.AbsolutePosition.Y - F2.AbsolutePosition.Y
    local Mag = (
        Vector2.new(F1.AbsolutePosition.X, F1.AbsolutePosition.Y) 
        - Vector2.new(F2.AbsolutePosition.X, F2.AbsolutePosition.Y)
    )
    local CenterPosition = (F2.AbsolutePosition + F1.AbsolutePosition) / 2
    Frame.Rotation = DivideSmaller(XLength, YLength)
    Frame.Position = UDim2.fromOffset(CenterPosition.X, CenterPosition.Y)
    Frame.Size = UDim2.fromOffset(Mag.Magnitude, .5)
end)

Frame.Parent = script.Parent
Frame.AnchorPoint = Vector2.new(0.5, 0.5)
5 Likes

For that exact effect you can just place 2 attachments (at player position and target position) and create a beam between them. You don’t really need UI here. Another thing is creating a part from your character to target and adding a decal to it or a billboard Gui if that suits you more.

3 Likes

Thanks for your idea. It’s great, but not what I’m looking for, I’m afraid.

1 Like

Unfortunate, maybe this code will work? I used this instead of editing yours as I don’t understand most of the stuff you did and felt they were random.

local RunService = game:GetService("RunService")
local Players = game:GetService("Players")

local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")

local currentCamera = workspace.CurrentCamera

workspace:WaitForChild("Part")

local line = Instance.new("Frame")
line.AnchorPoint = Vector2.new(0.5, 0.5)
line.Size = UDim2.new()
line.Parent = script.Parent

-- This is a separate function in case you want to add something to it.
local function getPosition2D(vector3: Vector3): Vector2
	return currentCamera:WorldToScreenPoint(vector3)
end

local function update(line: Frame)
	local origin = getPosition2D(humanoidRootPart.Position)
	local endPoint = getPosition2D(game.Workspace.Part.Position)
	local netVector = endPoint - origin
	
	local length = math.sqrt(netVector.X ^ 2 + netVector.Y ^ 2)
	local midpoint = Vector2.new((origin.X + endPoint.X) / 2, (origin.Y + endPoint.Y) / 2)
	local theta = math.deg(math.atan2(originY - endPointY, originX - endPointX))
	
	line.Position = UDim2.fromOffset(midpoint.X, midpoint.Y)
	line.Rotation = theta
	line.AnchorPoint = Vector2.new(.5, .5)
	line.Size = UDim2.new(0, length, 0, 2)
end

RunService.RenderStepped:Connect(function(deltaTime: number)
	update(line)
end
2 Likes

The code now works! I’m truly grateful for your help and time. :slightly_smiling_face:

2 Likes

But tho, i have a problem with your code. It sometimes gets linked into air, how can we fix this?

Video:

I had something working then I realized it had this same bug :< Ill try and find a fix for it.

2 Likes

Would hiding the line once the target goes off screen work? If it does then this should work

local RunService = game:GetService("RunService")
local Camera = workspace.CurrentCamera

local Target = workspace:WaitForChild("Target")

local LineFrame = script.Parent:WaitForChild("LineFrame")
local StartPosition = script.Parent:WaitForChild("StartPosition")
local TargetPosition = script.Parent:WaitForChild("TargetPosition")

local Atan2 = math.atan2
local Sqrt = math.sqrt
local Deg = math.deg

local VECTOR2_HALF = Vector2.new(0.5, 0.5)

local function drawLineFromTwoPoints(pointA, pointB)

	LineFrame.Size = UDim2.fromOffset(
		Sqrt((pointA.X - pointB.X) ^ 2 + (pointA.Y - pointB.Y) ^ 2), 
		2
	)
	LineFrame.Position = UDim2.fromOffset(
		(pointA.X + pointB.X) / 2, 
		(pointA.Y + pointB.Y) / 2
	)
	LineFrame.Rotation = Deg(Atan2(
		(pointA.Y - pointB.Y), (pointA.X - pointB.X)
		))

	LineFrame.AnchorPoint = VECTOR2_HALF
end

function drawLineUI(obj1, obj2)
	-- Get center regardless of anchor point
	local posA = obj1.AbsolutePosition + (obj1.AbsoluteSize * VECTOR2_HALF)
	local posB = obj2.AbsolutePosition + (obj2.AbsoluteSize * VECTOR2_HALF)

	return drawLineFromTwoPoints(posA, posB)
end




RunService.RenderStepped:Connect(function()
	local UiPosition, IsOnScreen = Camera:WorldToScreenPoint(Target.Position)
	if IsOnScreen then
		script.Parent.LineFrame.Visible = true
		script.Parent.TargetPosition.Position = UDim2.new(0, UiPosition.X, 0, UiPosition.Y)
	else
		script.Parent.LineFrame.Visible = false
	end
	drawLineUI(StartPosition, TargetPosition)
end)

If not, then tell me and ill try to find something else

4 Likes

Yes, you need to check if the target is offscreen, the getPosition2D function should return a boolean too which indicates whether or not the item is on screen, if that boolean is false for either of the parts then just hide the line.

3 Likes

Thank you all for helping me out! @CodyTheDwagon it works perfectly as i wanted it to be! Thank you @msix29 assisting me!!! I would give both of you solutions but its not letting me :confused: Ya’ll really good at math!

I’m happy I was able to help :3

3 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.