touchingFire variable getting jjammed at true

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    To be able to add heat when close to a fire and lose heat when far away
  2. What is the issue? Include screenshots / videos if possible!
    one variable keeps getting jammed at true
  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    Yes, but nothing really fit the issue
    After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!

local script for heatbar gui

local heat = 100
local maxHeat = 100
local isTouchingFire = script.Parent.Parent.Parent.Parent.Parent.IsTouchingFire
local runService = game:GetService("RunService")
local workspace = game:GetService("Workspace")
local touchingFire = isTouchingFire.Value

local function updateHeatUI()
	script.Parent.Size = UDim2.new(math.clamp(heat / maxHeat, 0, 1), 0, 1, 0)
	print(heat .."/".. maxHeat)
	print(touchingFire)
end

runService.Heartbeat:Connect(function(deltaTime)
	touchingFire = isTouchingFire.Value
	if isTouchingFire.Value == true and math.round(heat) <= maxHeat then
		heat = heat + 2 * deltaTime
	elseif touchingFire ~= true and math.round(heat) >= 0 then
		heat = heat - 1 * deltaTime
	elseif heat > maxHeat then
		heat = heat - 1
	else
		heat = heat
	end
	updateHeatUI()
end)

script for firebox:

local firebox = script.Parent
local Players = game:GetService("Players")


local touchingPlayers = {}

function OnTouched(otherPart)
	-- Checking if the other part is a body part of a player
	if otherPart.Parent:FindFirstChildWhichIsA("Humanoid") then
		if not table.find(touchingPlayers, otherPart.Parent) then
			table.insert(touchingPlayers, otherPart.Parent)
			local player = Players:GetPlayerFromCharacter(otherPart.Parent)  -- get the player whose character is in the workspace
			local playerGui = player.PlayerGui
			playerGui.IsTouchingFire.Value = true
		end
	end
end

function OnTouchEnded(otherPart)
	-- index is the position of the player in the table
	local index = table.find(touchingPlayers, otherPart.Parent)
	if index then
		local player = touchingPlayers[index]

		-- Check if any other body parts of the player is touching the hitbox
		local isPartOfPlayerInHitbox = false
		for _, part in firebox:GetTouchingParts() do
			if part:IsDescendantOf(player) then
				isPartOfPlayerInHitbox = true
				break
			end
		end

		-- If player is not inside the hitbox, then remove him from the table 
		if not isPartOfPlayerInHitbox then
			local player = table.find(touchingPlayers, index)
			local playerGui = player.PlayerGui
			playerGui.IsTouchingFire.Value = false
			table.remove(touchingPlayers, index)
		
		end

	end
end
firebox.TouchEnded:Connect(OnTouchEnded)
firebox.Touched:Connect(OnTouched)
1 Like

You got a bit careless here with your variable naming, and causing your problem. What you stored in touchingPlayers isn’t Player references, its references to their Player.Character Models.
So when you get to this line:

local playerGui = player.PlayerGui

You’re not working with a Player, you’re trying to find PlayerGui inside their character Model. You should name the variable character so that you won’t forget to do the Players:GetPlayerFromCharacter call before trying to access the PlayerGui.

It looks like the player you are getting is the character, if I’m not mistaken. This would create an issue trying to get the PlayerGui from the character, I think.
Instead, you might want to get the player from the character like you did before.

I have decided to change my path a bit, and now use events. My main issue now is that the false variable sometimes isn’t triggered.

Server-side:

local firebox = script.Parent
local Players = game:GetService("Players")
local rs = game:GetService("ReplicatedStorage")
local event = rs.PlayerTouchedFire


local touchingPlayers = {}

function OnTouched(otherPart)
	-- Checking if the other part is a body part of a player
	if otherPart.Parent:FindFirstChildWhichIsA("Humanoid") then
		if not table.find(touchingPlayers, otherPart.Parent) then
			table.insert(touchingPlayers, otherPart.Parent)
			event:FireClient(game.Players:FindFirstChild(otherPart.Parent.Name), "true")
			print(game.Players:FindFirstChild(otherPart.Parent.Name))
		end
	end
	-- index is the position of the player in the table
	local index = table.find(touchingPlayers, otherPart.Parent)
	if index then
		local player = touchingPlayers[index]

		-- Check if any other body parts of the player is touching the hitbox
		local isPartOfPlayerInHitbox = false
		for _, part in firebox:GetTouchingParts() do
			if part:IsDescendantOf(player) then
				isPartOfPlayerInHitbox = true
				break
			end
		end

		-- If player is not inside the hitbox, then remove him from the table 
		if not isPartOfPlayerInHitbox then
			print(player.Name)
			event:FireClient(game.Players:FindFirstChild(player.Name), "false")
			table.remove(touchingPlayers, index)
		end
	end
end

firebox.Touched:Connect(OnTouched)

Specifically this part of the code is what i am thinking is the issue:

-- If player is not inside the hitbox, then remove him from the table 
		if not isPartOfPlayerInHitbox then
			print(player.Name)
			event:FireClient(game.Players:FindFirstChild(player.Name), "false")
			table.remove(touchingPlayers, index)
		end

Client-side:

local heat = 100
local maxHeat = 100
local runService = game:GetService("RunService")
local workspace = game:GetService("Workspace")
local touchingFire = false
local rs = game:GetService("ReplicatedStorage")
local event = rs.PlayerTouchedFire

local function updateHeatUI()
	script.Parent.Size = UDim2.new(math.clamp(heat / maxHeat, 0, 1), 0, 1, 0)
	print(heat .."/".. maxHeat)
	print(touchingFire)
end

local function updateTouchingFire(bool)
	--print(game.Players.LocalPlayer .. "fired" .. tostring(bool))
	if bool == "true" then
		touchingFire = true
	elseif bool ~= "false" then
		warn("errow with bool")
	else
		touchingFire = false
	end
end

runService.Heartbeat:Connect(function(deltaTime)
	if touchingFire == true and math.round(heat) <= maxHeat then
		heat = heat + 2 * deltaTime
	elseif touchingFire ~= true and math.round(heat) >= 0 then
		heat = heat - 1 * deltaTime
	else
		heat = heat
	end
	updateHeatUI()
end)

event.OnClientEvent:Connect(updateTouchingFire)

One thing I would recommend is to simply set touchingFire to bool by making the value of bool either true or false without quotation marks.

So instead of that code above, after changing the argument passed to either true or false, just check if bool exists (if bool ~= nil) and then set touchingFire to bool if it exists.

So when you fire the event with bool false it should be:
event:FireClient(game.Players:FindFirstChild(player.Name), false)

so its not the local script thats the issue, its the server-side script. any tips to improve it?

For one, I’d probably rename the event variable to a more specific name, just so you know more what it does.
Also, why are you checking if the touching part is a player, but then checking if part of the player is in the hitbox?

  1. the event is ‘is touching fire’
  2. this is a sample code bit brought by @Rival615
local firebox = script.Parent
local hitbox: BasePart = firebox.Hitbox

local touchingPlayers = {}

function OnTouched(otherPart)
	-- Checking if the other part is a body part of a player
	if otherPart.Parent:FindFirstChildWhichIsA("Humanoid") then
		if not table.find(touchingPlayers, otherPart.Parent) then
			table.insert(touchingPlayers, otherPart.Parent)
		end
	end
end

function OnTouchEnded(otherPart)
	-- index is the position of the player in the table
	local index = table.find(touchingPlayers, otherPart.Parent)
	if index then
		local player = touchingPlayers[index]
		
		-- Check if any other body parts of the player is touching the hitbox
		local isPartOfPlayerInHitbox = false
		for _, part in hitbox:GetTouchingParts() do
			if part:IsDescendantOf(player) then
				isPartOfPlayerInHitbox = true
				break
			end
		end
		
		-- If player is not inside the hitbox, then remove him from the table 
		if not isPartOfPlayerInHitbox then
			table.remove(touchingPlayers, index)
			
			-- Lower the player's heat here
		end
		
	end
end


hitbox.TouchEnded:Connect(OnTouchEnded)
hitbox.Touched:Connect(OnTouched)

Okay, that’s what I figured.
What you need to do is do as @Rival615 did and separate the two checks into OnTouched and OnTouchEnded. This way, it knows to check if there are parts touching it after the touch is ended, and not just once when the touch starts.

function OnTouched(otherPart)
	-- Checking if the other part is a body part of a player
	if otherPart.Parent:FindFirstChildWhichIsA("Humanoid") then
		if not table.find(touchingPlayers, otherPart.Parent) then
			table.insert(touchingPlayers, otherPart.Parent)
			event:FireClient(game.Players:FindFirstChild(otherPart.Parent.Name), true)
			print(game.Players:FindFirstChild(otherPart.Parent.Name))
		end
	end
end
function OnTouchEnded(otherPart)
-- index is the position of the player in the table
	local index = table.find(touchingPlayers, otherPart.Parent)
	if index then
		local player = touchingPlayers[index]

		-- Check if any other body parts of the player is touching the hitbox
		local isPartOfPlayerInHitbox = false
		for _, part in firebox:GetTouchingParts() do
			if part:IsDescendantOf(player) then
				isPartOfPlayerInHitbox = true
				break
			end
		end

		-- If player is not inside the hitbox, then remove him from the table 
		if not isPartOfPlayerInHitbox then
			print(player.Name)
			event:FireClient(game.Players:FindFirstChild(player.Name), false)
			table.remove(touchingPlayers, index)
		end
	end
end

firebox.Touched:Connect(OnTouched)
firebox.TouchEnded:Connect(OnTouchEnded)

so what i think is happening is that the event is firing but the client can’t pick it up, either that or it can’t recognize it.

Could I see both scripts again? Both client and server.

1 Like

sure:

Server-side:

local firebox = script.Parent
local Players = game:GetService("Players")
local rs = game:GetService("ReplicatedStorage")
local event = rs.PlayerTouchedFire

local touchingPlayers = {}

function OnTouched(otherPart)
	-- Checking if the other part is a body part of a player
	if otherPart.Parent:FindFirstChildWhichIsA("Humanoid") then
		if not table.find(touchingPlayers, otherPart.Parent) then
			table.insert(touchingPlayers, otherPart.Parent)
			event:FireClient(game.Players:FindFirstChild(otherPart.Parent.Name), true)
			print(game.Players:FindFirstChild(otherPart.Parent.Name))
		end
	end
end
function OnTouchEnded(otherPart)
	-- index is the position of the player in the table
	local index = table.find(touchingPlayers, otherPart.Parent)
	if index then
		local player = touchingPlayers[index]

		-- Check if any other body parts of the player is touching the hitbox
		local isPartOfPlayerInHitbox = false
		for _, part in firebox:GetTouchingParts() do
			if part:IsDescendantOf(player) then
				isPartOfPlayerInHitbox = true
				break
			end
		end

		-- If player is not inside the hitbox, then remove him from the table 
		if not isPartOfPlayerInHitbox then
			print(player.Name)
			event:FireClient(game.Players:FindFirstChild(player.Name), false)
			table.remove(touchingPlayers, index)
		end
	end
end

firebox.Touched:Connect(OnTouched)
firebox.TouchEnded:Connect(OnTouchEnded)

Client-side:

local heat = 100
local maxHeat = 100
local runService = game:GetService("RunService")
local workspace = game:GetService("Workspace")
local touchingFire = false
local rs = game:GetService("ReplicatedStorage")
local event = rs.PlayerTouchedFire

local function updateHeatUI()
	script.Parent.Size = UDim2.new(math.clamp(heat / maxHeat, 0, 1), 0, 1, 0)
	print(heat .."/".. maxHeat)
	print(touchingFire)
end

local function updateTouchingFire(bool)
	--print(game.Players.LocalPlayer .. "fired" .. tostring(bool))
	if bool then
		if bool == true then
			touchingFire = true
		else
			touchingFire = false
		end
	end
end

runService.Heartbeat:Connect(function(deltaTime)
	if touchingFire == true and math.round(heat) <= maxHeat then
		heat = heat + 2 * deltaTime
	elseif touchingFire ~= true and math.round(heat) >= 0 then
		heat = heat - 1 * deltaTime
	else
		heat = heat
	end
	updateHeatUI()
end)

event.OnClientEvent:Connect(updateTouchingFire)

ignore the commented out print line, that was giving me some trouble

In the client script:

if bool ~= nil then
	touchingFire = bool
end

Replace this:

if bool then
	if bool == true then
		touchingFire = true
	else
		touchingFire = false
	end
end

You don’t want to just do “if bool” because that is checking the value of the bool. It is the equivalent of “if bool == true”.

i have done something similar but the true value keeps getting jammed at true, maybe its the server-side, because it does go to false from true very rarely

You have tried what I wrote specifically and it does not work?

its more server side, you were just editing the client. i think it has to do with the event not firing properly.

Yes, I know. I’m just wondering if you’ve tried what I just said on the client side. It wouldn’t hurt to try it out to see if it solves anything.
I’m currently reviewing the server script. Just try out the edits I have suggested for the client for now, and I will get back to you about the server script.

i have tried, and thanks for your help! to give some context, this is for a game i am working on, similar to ‘A dusty trip’ and ‘dead rails’ (except you don’t have a car nor train, only c a b i n and the terrain is randomly generated). Its called ‘snowed in’

Modified your code a little, this is assuming that your PlayerGui variable is infact referencing to what it’s meant to and you did not intentionally try to retrieve PlayerGui from the character.

local firebox = script.Parent
local Players = game:GetService("Players")

local touchingPlayers = {}

function onTouched()
    local currentlyTouching = {}
    for _, Part in pairs(firebox:GetTouchingParts()) do
        
        local Player = Players:GetPlayerFromCharacter(Part.Parent)
        
        if Player and not table.find(currentlyTouching, Player) then
            table.insert(currentlyTouching, Player)
        end
    end
    
    for _, Player in ipairs(touchingPlayers) do
        local IsTouchingFire = Player.PlayerGui:FindFirstChild("IsTouchingFire")

        if not IsTouchingFire then continue end
        if table.find(currentlyTouching, Player) then
            IsTouchingFire.Value = true
        else
            IsTouchingFire.Value = false 
        end
    end
    touchingPlayers = currentlyTouching
end

firebox.Touched:Connect(onTouched)
firebox.TouchEnded:Connect(onTouched)

the ‘is touching’ is handled by the client and is triggered by a remote event. plus, i tried that approach and it didn’t work