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 if player is inside radius without looping?

From what I understand, is that while loops can make a game lag, so when making this script, I tried to find an alternative that does not use while wait do, but I couldn't find any :( My goal is so that when I player walks into the preset radius, it changes a value inside of them, So that another script that is looping through the players it finds the players with the changed value, and goes on from there. Everything works, but I want to improve my game by reducing possible lag.

while wait() do
for i,v in pairs (game:GetService("Players"):GetPlayers()) do
	if v.Character then
		if (Vector3.new(-5.15, 6.05, 8.4) - v.Character:WaitForChild("HumanoidRootPart").Position).magnitude <= 6 then
			if v:WaitForChild("Settings"):WaitForChild("currently_inside_lobby_elevator").Value ~= true then
				v:WaitForChild("Settings"):WaitForChild("currently_inside_lobby_elevator").Value = true
				game:GetService("ReplicatedStorage"):WaitForChild("RE"):WaitForChild("LobbyElevator"):FireClient(v,true)
			end
		end
	end
end
end

Keep in mind this is running from a serverscript

2 comments

0

Run the loop from the client

0

you can use Humanoid's Running event

1 answer

✓ Accepted answer

Explanation

If you don't want to use a loop to determine the magnitude, you can use a :GetPropertyChangedSignal() event to determine changes in the player's character model (note that some of these, like position will not be accounted for once they have loaded into the workspace)

To get the player's character, we will be using the CharacterAdded event of the player's instance, which is taken from when the player joins the game.

One of these properties, the Humanoid's MoveDirection (which changes when the player moves outside of a straight line) can be used as an optional connection to determine the difference in magnitude.

Revised Server Script (Move Direction)

game:GetService("Players").PlayerAdded:Connect(function(Player)
	Player.CharacterAdded:Connect(function(Character)
		local human = Character:WaitForChild("Humanoid")
		local root = Character:WaitForChild("HumanoidRootPart")
	    human:GetPropertyChangedSignal("MoveDirection"):Connect(function()
			if (Vector3.new(-5.15, 6.05, 8.4) - root.Position).magnitude <= 6 then
				local elev = Player:WaitForChild("Settings"):WaitForChild("currently_inside_lobby_elevator")
				local remote = game:GetService("ReplicatedStorage"):WaitForChild("RE"):WaitForChild("LobbyElevator")
				if elev.Value ~= true then
					elev.Value = true
					remote:FireClient(Player, true)
				end
			end
		end)
	end)
end)

However, since a player might move in a straight line to reach the preferred magnitude, we can use .Touched events to check the magnitude since as a player moves, they must touch a surface at some point.

Revised Server Script (.Touched Event)

game:GetService("Players").PlayerAdded:Connect(function(Player)
	Player.CharacterAdded:Connect(function(Character)
		Character.AncestryChanged:Connect(function(child, parent)
			if parent == workspace then
				for i, v in pairs(Character:GetDescendants()) do
					if v:IsA("BasePart") then
						v.Touched:Connect(function()
							local root = Character:WaitForChild("HumanoidRootPart")
							if (Vector3.new(-5.15, 6.05, 8.4) - root.Position).magnitude <= 6 then
								local elev = Player:WaitForChild("Settings"):WaitForChild("currently_inside_lobby_elevator")
								local remote = game:GetService("ReplicatedStorage"):WaitForChild("RE"):WaitForChild("LobbyElevator")
								if elev.Value ~= true then
									elev.Value = true
									remote:FireClient(Player,true)
								end
							end
						end)
					end
				end
			end
		end)
	end)
end)

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