Need help passing Boolean value with remote function

Hey all! I’m working on a system for my game where you rack up points based on how long someone has been flying/moving and I am having some troubles with the local script side of things. I feel like I may be going about it the wrong way as well so any pointers I’ll take!

As previously stated, I do not know how to get the points value to stop ticking up on the GUI even after the while loop on the server side has finished and returns a Boolean to the local script.


I’ve tried various things such as using a remote function, but that only returns a value AFTER everything has ran. I could use 2 client firing events but that seems clunky. I liked that idea of using the client event twice though so what I’m trying is to fire one client event with 2 different Boolean values but I don’t quite understand how it works. I will leave the script bellow so you all can see what I am talking about.
Local Script:

local replicatedStorage = game:GetService("ReplicatedStorage")
local eventCalls = replicatedStorage:WaitForChild("LocalEventCalls")
local pointsEvent = eventCalls:WaitForChild("PointsEvent")

local pointsGUI = script.Parent
local pointAmount = pointsGUI.Frame["Point Amount"]

local pointCounter = 0
	
pointsEvent.OnClientEvent:Connect(function(addingPoints)
	pointsGUI.Enabled = true
	print("Client fired")

	while addingPoints == true do

		pointAmount.Text = pointCounter
		pointCounter += 1
		
		if addingPoints == false then --Currently not functioning
			print("Not true anymore")
			break
		end
		task.wait()
	end
end)

Module Script:

	local addingPoints = true
	pointsEvent:FireClient(player, addingPoints)
	
	while addingPoints == true do
		local distance = (humanPlayer.Position - victimRootPart.Position).Magnitude
		--print(math.ceil(distance))
		
		print("Player is moving")
		
		if victimRootPart.Velocity.Magnitude < 0.1 then
			addingPoints = false
			pointsEvent:FireClient(player, addingPoints)
			--print("Player has stopped")
			return distance
		end
		task.wait()
	end

As a bonus, if there is any way that I can directly plug the currently flung distance into the GUI element so that it’s accurate that would be wildly appreciated. Thanks!

Hello! First of all i wanted to mention the fact your script is pretty unoptimised i recommend using RunService.Heartbeat instead of the while loop. Also can you explain which booleans you want to send? It provides more context.

Since you’re passing the value through a RemoteEvent, it creates a copy of the boolean’s value, not the current value. This means if you change the boolean on the server, it doesn’t affect the copy of the boolean.

To solve this, you can create a BooleanValue on the Player (In PlayerService Or The Character) and change the boolean through there. You can replace the RemoteEvents entirely and just switch it out for a .Changed event signal and THEN run the loop there.
So something like:

Local Script

local RunService = game:GetService("RunService")
local player = game:GetService("Players").LocalPlayer

local pointCounter = 0

local addingPoints = player:WaitForChild("AddingPoints")

local function addPoints()

	if addingPoints.Value == true then
		pointCounter += 1
		print(pointCounter)
		-- Additional Code here
	end
	
	-- You dont need an extra check to see if the boolean is set to false unless you want extra code
	
end

RunService.Heartbeat:Connect(addPoints)

Server Script:

local addingPoints = player.AddingPoints
local RunService = game:GetService("RunService")

function checkPoints()
	while addingPoints.Value == true do
		local distance = (humanPlayer.Position - victimRootPart.Position).Magnitude
		--print(math.ceil(distance))

		print("Player is moving")

		if victimRootPart.Velocity.Magnitude < 0.1 then
			addingPoints.Value = false
			--print("Player has stopped")
			return distance
		end
	end
end

checkPoints()

You can do something like this so the server and client can communicate to eachother properly.

You can use the task library to solve this issue:

local replicatedStorage = game:GetService("ReplicatedStorage")
local eventCalls = replicatedStorage:WaitForChild("LocalEventCalls")
local pointsEvent = eventCalls:WaitForChild("PointsEvent")

local pointsGUI = script.Parent
local pointAmount = pointsGUI.Frame["Point Amount"]

local pointCounter = 0
local thread = nil

local function addPointsLoop()
	while true do -- Using task.cancel will stop this loop from running, even though it's a while true do loop
		pointAmount.Text = pointCounter
		pointCounter += 1

		task.wait()
	end
end

pointsEvent.OnClientEvent:Connect(function(addingPoints)
	pointsGUI.Enabled = true
	print("Client fired")

	if addingPoints == true then
		if thread == nil then -- If a thread exists, do not start a new loop
			thread = task.spawn(addPointsLoop)
		end
	else
		if thread then
			task.cancel(thread)
			thread = nil

			print("Not true anymore")
		end
	end
end)

Edit: I forgot to add an end. The code should work correctly now :slight_smile::+1:

1 Like

Hey! Didn’t know much about heartbeat but after reading into it and understanding your solution its worked out quite well! Though this is marked as a solution already there’s one more thing I would like to ask. How would I reference the other players root part in the local script so I can have a counter on the screen showing in real time how far the other person is traveling? I will send new images with the updated code if you would like to take a quick look at it.
Module Script:

	local addingPoints = player:WaitForChild("AddingPoints")
	
	local function checkPoints()
		addingPoints.Value = true
		
		while addingPoints.Value == true do
			local distance = (humanPlayer.Position - victimRootPart.Position).Magnitude
			print(math.ceil(distance))
			print("Player is moving")
			
			if victimRootPart.Velocity.Magnitude < 0.1 then
				addingPoints.Value = false
				
				player.leaderstats.Score.Value += math.ceil(distance)
			end
			
			task.wait()
		end
	end
	checkPoints()
end

return module

Local Script:

local pointCounter = 0
local addingPoints = player:WaitForChild("AddingPoints")

local function addPoints() 
	if addingPoints.Value == true then
	local distance = (hrp.Position).Magnitude --How would I reference the other player so I can show the distance in a GUI???
	print(distance)
	--print(pointCounter)
	end
end

runService.Heartbeat:Connect(addPoints)

Sorry to poke you about what is probably another minor issue, just the small bumps you run into when learning game development for the first time.
Thanks!

local player = game:GetService('Players').LocalPlayer -- Gets the player (only works on LocalScripts)
local char = player.Character or player.CharacterAdded:Wait() -- Gets the player's Character or waits for it to load/be added in

player.CharacterAdded:Connect(function(newCharacter) -- When character respawns or gets added
	char = newCharacter -- set the char variable to the new character
end)

you can reference the rootpart directly using char.PrimaryPart or create a new variable that updates when the CharacterAdded signal is triggered, so itll be something like:

loacl hrp = char.PrimaryPart

player.CharacterAdded:Connect(function(newCharacter) -- When character respawns or gets added
	char = newCharacter -- set the char variable to the new character
	hrp = newCharacter.PrimaryPart
end)

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