Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How to find more then one brick?

Ok so I'm trying to make a cell service with cell towers so when a player is close or far it will act like a cellphone but I'm having troubles finding more then one brick. How can I have this find more then one brick?

local part = game.Workspace.Cell:GetChildern() -- I want this to find everything in the Model Cell but don't know how to add it to the purtion of the script below...
while true do
	for i,v in pairs(game.Players:GetChildren()) do
		if (v.Character.Torso.Position - part.Position).magnitude <= 50 then
			v.PlayerGui.ScreenGui.TextLabel.Text = "-----"
		elseif (v.Character.Torso.Position - part.Position).magnitude <= 100 then
			v.PlayerGui.ScreenGui.TextLabel.Text = "----"
		elseif (v.Character.Torso.Position - part.Position).magnitude <= 150 then
			v.PlayerGui.ScreenGui.TextLabel.Text = "---"
		elseif (v.Character.Torso.Position - part.Position).magnitude <= 200 then
			v.PlayerGui.ScreenGui.TextLabel.Text = "--"
		elseif (v.Character.Torso.Position - part.Position).magnitude <= 250 then
			v.PlayerGui.ScreenGui.TextLabel.Text = "-"
		elseif (v.Character.Torso.Position - part.Position).magnitude <= 300 then
			v.PlayerGui.ScreenGui.TextLabel.Text = "No Service"
		end
	end
	wait()
end

2 answers

✓ Accepted answer

What you should do is, while you're iterating through the players then you need to iterate through the cell towers as well, store all the magnitudes in a table, then use the table.sort function to find the smallest index in the table(the first index).. and finally use your conditionals from line 4 - line 16.

local parts = workspace.Cell:GetChildren()

while wait() do
	--Iterate through players
	for i,v in pairs(game.Players:GetPlayers()) do
		--Define a table for all the magnitudes
		local mags = {}
		--Iterate through parts
		for a,b in pairs(parts) do
			--Make sure the character has a torso
			if v.Character:FindFirstChild('Torso') then
				--Get the distance
				local mag = (b.CFrame.p - v.Character.Torso.CFrame.p).magnitude
				--Insert the distance into the table
				table.insert(mags,mag)
			end
		end
		--Sort the table from least to greatest
		table.sort(mags)
		--Get the lowest value
		local val = mags[1]
		--Use the conditionals with the 'val' variable
		if val <= 50 then
			v.PlayerGui.ScreenGui.TextLabel.Text = "-----"
		elseif val <= 100 and val > 50 then
			v.PlayerGui.ScreenGui.TextLabel.Text = "----"
		elseif val <= 150 and val > 100 then
			v.PlayerGui.ScreenGui.TextLabel.Text = "---"
		elseif val <= 200 and val > 150 then
			v.PlayerGui.ScreenGui.TextLabel.Text = "--"
		elseif val <= 250 and val > 200 then
			v.PlayerGui.ScreenGui.TextLabel.Text = "-"
		else
			v.PlayerGui.ScreenGui.TextLabel.Text = "No Service"
		end
	end
end

10 comments

0

Tried I got this error now attempt to compare two userdata values on line 20...

0

which on here is line 21 plr was not defined...

0

Edited

0

Why use a table when you could just keep track of a "bestMagnitude" value? No need to sort a table of values that you aren't going to use. Further, what's the point of adding "and val > 50" on line 25? "val > 50" is guaranteed by line 23's conditional not being true. Also, any particular reason you're using .CFrame.p instead of .Position ? Finally, I'd recommend replacing line 33 with "else"

0

This way I just though it would be easier, since the table.sort function exists. Idk, doesn't really matter. I'm using CFrame.p since I normally deal with CFrames, rather than Vectors - Just a habbit. That last suggestion was actually good. Why critisize my code if it works effectively and for the most part efficiently, though?

0

There's no point in going for a slightly more efficient method when the readability is awful. People can understand my code better than yours and the changes you made aren't really worth changing. A few millaseconds worth of increased performance rate isn't worth making the code ugly.

0

It just seems like unnecessary processing. Sorry, I suppose I'm "prematurely optimizing".

0

What part of my code is so ugly? (If you just mean line 18, I can agree it's harder to understand (though potentially more powerful))

0

'ugly' is a strong word but yes.. 18 is harder to read / understand. But like I said, trading in readability for miniscule performance rate enhancement isn't worth it.. if you're giving an answer to the public.

0

Thx Goulstem!

You need to add another loop.

while true do
	local cells = game.Workspace.Cell:GetChildern()
	local players = game.Players:GetChildren()
	for i = 1, #players do
		if players[i].Character and players[i].Character:FindFirstChild("Torso") then
			local pos = players[i].Character.Torso.Position
			local bestDist = 251 --since max signal distance is 250
			for j = 1, #cells do
				local dist = (cells[j].Position - pos).magnitude
				if dist < bestDist then
					bestDist = dist
					--If you want to store the closest cell tower, do so here (it will equal "cells[j]")
				end
			end
			if bestDist > 250 then
				players[i].PlayerGui.ScreenGui.TextLabel.Text = "No Service"
			else
				players[i].PlayerGui.ScreenGui.TextLabel.Text = string.rep("-", math.min(5, math.floor((300-bestDist)/50)))
			end
		end
	end
	wait()
end

Note that putting the "game.Workspace.Cell:GetChildern()" inside the while loop will mean that if you add/remove cell towers as the game progresses, the script will automatically adapt to that. If you don't intend to add/remove towers, this line can stay outside the while loop.

players[i].PlayerGui.ScreenGui.TextLabel.Text = string.rep("-", math.min(5, math.floor((300-bestDist)/50))) acts the same as the majority of the 'if' statements you had previously. Along with the if bestDist > 250 then, all cases are taken care of (whereas before, if 'magnitude' was 301, your if statements could not handle it and would not update the TextLabel).

This discussion is preserved as it was. New answers, comments, and votes are closed.