You can write your topic however you want, but you need to answer these questions:
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
What is the issue? Include screenshots / videos if possible!
one variable keeps getting jammed at true
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)
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)
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?
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)
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
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
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)