How to make a distance gui

Hey! Thanks so much, is it possible if you could walk me through this line’s math, and what each element of it does? (In depth if possible) Thankyou!

local XVal = math.clamp((AM.X + Main.AbsolutePosition.X) * (percentage),Main.AbsolutePosition.X,Main.AbsolutePosition.X + AM.X)
1 Like

Also, my code doesn’t seem to be working. The imagelabel just never shows up! Any feedback?

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

local frame = script.Parent

local start = game.Workspace:WaitForChild("Start")
local endPos = game.Workspace:WaitForChild("End")

local pDist = (start.Position-endPos.Position).Magnitude

local function check(name)
	local tbl = {}
	for _, v in pairs(game.Players:GetPlayers()) do
		table.insert(tbl, v.Name)
	end
	
	if table.find(tbl,name) then
		return false
	else
		return true
	end
end

local canRun = false

task.wait(5)

canRun = true

RunService.RenderStepped:Connect(function()
	if canRun == false then return end
	for i, plr in ipairs(game.Players:GetPlayers()) do
		local char = plr.Character 
		local plrDist = plr:DistanceFromCharacter(game.Workspace.Start.Position)
		local percentage = (plrDist/pDist)
		
		if frame:FindFirstChild(plr.Name) then
			print("Yes")
			local imageLabel = frame[plr.Name]
			
			local bool = check(imageLabel.Name)
			if bool then
				print("NO")
				imageLabel:Destroy()
			else
				local AD = imageLabel.AbsoluteSize
				local AM = frame.AbsoluteSize

				local XVal = math.clamp((AM.X + frame.AbsolutePosition.X) * (percentage),frame.AbsolutePosition.X,frame.AbsolutePosition.X + AM.X)

				imageLabel.Position = UDim2.new(0,XVal,0,frame.AbsolutePosition.Y)
			end
		else
			local userId = plr.UserId
			local thumbType = Enum.ThumbnailType.HeadShot
			local thumbSize = Enum.ThumbnailSize.Size420x420
			local content, isReady = Players:GetUserThumbnailAsync(userId, thumbType, thumbSize)

			local imageLabel = Instance.new("ImageLabel")
			imageLabel.Parent = frame
			imageLabel.Image = content
			imageLabel.Size = UDim2.new(0, 420, 0, 420)
			imageLabel.Name = plr.Name
			print(imageLabel)
			local AD = imageLabel.AbsoluteSize
			local AM = frame.AbsoluteSize

			local XVal = math.clamp((AM.X + frame.AbsolutePosition.X) * (percentage),frame.AbsolutePosition.X,frame.AbsolutePosition.X + AM.X)

			imageLabel.Position = UDim2.new(0,XVal,0,frame.AbsolutePosition.Y)
		end
	end
end)
2 Likes

Im not completely sure, but this also depends on how you’ve set up the UI itself. The big grey line and the white square is under the same screen gui and share the same space. Meaning in the workspace, they’re right next to each other in the hierarchy, that most definitely would pose a problem. I would recommend you to put the image label into frame.Parent instead, that may help.

3 Likes

Why would that do anything, and also that would kinda break the script as it is right now. Is there a way to change how we put the percentage onto the ui so that it in can be in the frame?

2 Likes

Sorry I didn’t respond. You can view my code.
Distance.rbxl (43.4 KB)

2 Likes

It wouldn’t break the script, or at least it shouldn’t, you should also move your ui the way I described and resize it accordingly. I’ll send you the place file if I get yours to work.

2 Likes

This is how I made it look now


However the little edgecase still remains which I’ll let you snuff out.
Distance.rbxl (43.8 KB)

3 Likes

Yeah, that’s what I did in my updated script.

3 Likes

Hi, thankyou, I obviously have to fix that bug and add the ability for multiple players to be on it, but thankyou. And sorry @kyler_josiah that I didn’t see yours sooner. Thanks guys

2 Likes

I have the entire thing (with no bugs). Just in case you want it:
Distance.rbxl (43.6 KB)

2 Likes

Hey, sorry for another reply, but when I tried implementing having multiple players in it, it doesn’t work anymore? Could you please help me, I have been trying to fix this and I can’t.

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

local frame = script.Parent

local start = game.Workspace:WaitForChild("Starting")
local endPos = game.Workspace:WaitForChild("GoTo")

local pDist = (start.Position-endPos.Position).Magnitude

local function check(name)
	local tbl = {}
	for _, v in pairs(game.Players:GetPlayers()) do
		table.insert(tbl, v.Name)
	end
	
	if table.find(tbl,name) then
		return false
	else
		return true
	end
end

local canRun = false

task.wait(2)

canRun = true

RunService.RenderStepped:Connect(function()
	if canRun == false then return end
	for i, plr in ipairs(game.Players:GetPlayers()) do
		
		if frame.Parent:FindFirstChild(plr.Name) then
			
		else
			local char = plr.Character 
			local plrDist = plr:DistanceFromCharacter(start.Position)
			local percentage = (plrDist/pDist)

			local userId = plr.UserId
			local thumbType = Enum.ThumbnailType.HeadShot
			local thumbSize = Enum.ThumbnailSize.Size420x420
			local content, isReady = Players:GetUserThumbnailAsync(userId, thumbType, thumbSize)
			repeat task.wait() until isReady
			if isReady then
				local imageLabel = frame.Parent:WaitForChild("PlayerIcon"):Clone()
				imageLabel.Parent = frame.Parent
				imageLabel.Name = plr.Name
				imageLabel.Player.Value = plr
				imageLabel.Image = content
				local AD = imageLabel.AbsoluteSize
				local AM = frame.AbsoluteSize

				local XVal = math.clamp((AM.X + frame.AbsolutePosition.X) * (percentage),frame.AbsolutePosition.X,frame.AbsolutePosition.X + AM.X)

				imageLabel.Position = UDim2.new(0,XVal,0,frame.AbsolutePosition.Y + frame.AbsoluteSize.Y)
			end
		end
	end
	
	for i, image in ipairs(frame.Parent:GetChildren()) do
		if image:IsA("ImageLabel") and image.Name ~= "PlayerIcon" then
			local bool = check(image.Name)
			
			if bool then
				image:Destroy()
			else
				local player = image:WaitForChild("Player").Value
				local char = player.Character
				
				local plrDist = player:DistanceFromCharacter(start.Position)
				local percentage = (plrDist/pDist)
				
				local AD = image.AbsoluteSize
				local AM = frame.AbsoluteSize

				local XVal = math.clamp((AM.X + frame.AbsolutePosition.X) * (percentage),frame.AbsolutePosition.X,frame.AbsolutePosition.X + AM.X)

				image.Position = UDim2.new(0,XVal,0,frame.AbsolutePosition.Y + frame.AbsoluteSize.Y)
			end
		end
	end
end)
2 Likes

My one also has multiple player support in it. Just saying

2 Likes

I have implemented your algorithm bc the other one was kinda hitchy, into my multiple players system and now none are showing up? Could you help me (will give solution to you) . It works when there is one player if that helps at all.

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

local frame = script.Parent

local start = game.Workspace:WaitForChild("Starting")
local endPos = game.Workspace:WaitForChild("GoTo")

local pDist = (start.Position-endPos.Position).Magnitude

local function check(name)
	local tbl = {}
	for _, v in pairs(game.Players:GetPlayers()) do
		table.insert(tbl, v.Name)
	end
	
	if table.find(tbl,name) then
		return false
	else
		return true
	end
end

local canRun = false

task.wait(2)

canRun = true

RunService.RenderStepped:Connect(function()
	if canRun == false then return end
	for i, plr in ipairs(game.Players:GetPlayers()) do
		
		if frame.Parent:FindFirstChild(plr.Name) then
			
		else
			local char = plr.Character 
			local plrDist = plr:DistanceFromCharacter(start.Position)
			local percentage = (plrDist/pDist)

			local userId = plr.UserId
			local thumbType = Enum.ThumbnailType.HeadShot
			local thumbSize = Enum.ThumbnailSize.Size420x420
			local content, isReady = Players:GetUserThumbnailAsync(userId, thumbType, thumbSize)
			repeat task.wait() until isReady
			if isReady then
				local imageLabel = frame.Parent:WaitForChild("PlayerIcon"):Clone()
				imageLabel.Parent = frame.Parent
				imageLabel.Visible = true
				imageLabel.Name = plr.Name
				imageLabel.Player.Value = plr
				imageLabel.Image = content
				local AD = imageLabel.AbsoluteSize
				local AM = frame.AbsoluteSize

				local XVal = math.clamp((AM.X + frame.AbsolutePosition.X) * (percentage),frame.AbsolutePosition.X,frame.AbsolutePosition.X + AM.X)

				imageLabel.Position = UDim2.new(0,XVal,0,frame.AbsolutePosition.Y + frame.AbsoluteSize.Y)
			end
		end
	end
	
	for i, image in ipairs(frame.Parent:GetChildren()) do
		if image:IsA("ImageLabel") and image.Name ~= "PlayerIcon" then
			local bool = check(image.Name)
			
			if bool then
				image:Destroy()
			else
				local player = image:WaitForChild("Player").Value
				local char = player.Character
				
				local playerPosition = player.Character and player.Character.HumanoidRootPart.Position
				local totalDistance = endPos.Position.X - start.Position.X
				local playerToPart1Distance = start.Position.X - playerPosition.X
				local percentageDistance = math.abs((playerToPart1Distance / totalDistance))

				if playerPosition.X < start.Position.X then
					percentageDistance = 0+image.Size.Width.Scale/2 - 0.05
				elseif playerPosition.X > endPos.Position.X then
					percentageDistance = 1-image.Size.Width.Scale/2 + 0.05
				end

				image.Position = UDim2.new(percentageDistance, 0, 0.85, 0)
			end
		end
	end
end)
2 Likes

Yeah for sure! Well as self explanatory the first part is, math.clamp clamps a value between two given numbers, here’s the documentation

What we’re doing is we’re clamping a value which we give it, which is the absolute size of the big slider + its absolute position, both in the X-axis, what this does, it gives us the starting position for the players icon to be at, here’s a terrible drawing to illustrate:

Then we multiply by the percentage, which is between 1 and 0. 0 Starting at the left side and 1 ending at the right and for example, .5 ending in the middle! Handy, right?. Then the minimum value we use for the clamp is the far left side of the bar, which is just it’s absolute position on the X-axis. While the max value is the far end. I apologize if I didn’t go into enough depth, I know I’d suck as a teacher haha. However, hope this helps.

3 Likes

Thank you so much! I think I understand it more now. Alas, is there any way you can help me fix the above code too or no?

2 Likes

Sure I’ll have a look at it. CHARS

3 Likes

Yeah so the code works perfectly fine, it’s just you’re not able to test in roblox studio with multiple players as the pseudo-players Player1 and Player2 don’t return a thumbnail. If you go in-game with actual players you’ll find it works.

3 Likes

Ahhhh alright thankyou sdsdfsdfsdfsdfsdf

2 Likes

Sorry I haven’t responded in a while. Why not just replace all of your code with my code, my code works completely fine, and works with multiple people.

2 Likes

I had to change it because it will only track multiple players at the start of the server, and if a player leaves it stays there

2 Likes