Your "died" function is trying to listen to an event, ie you're wanting to exit a loop when an event occurs. To do this, you listen to the event but save the connection you've made to a variable so that you can disconnect it when the loop ends. Inside the event listener, you change a boolean variable that you periodically check to see if you should keep running the loop. (This is shown below.)
Notes:
- you'll probably want to run that code every time the user touches the brick, so put it in a function (and add debounce - you don't want several 'while' loops running, all giving the player 100s of dollars every second)
- (Minor) Use
Connect, not connect (which is deprecated)
if user ~= nil then can be shortened to if user then so long as you don't expect user to ever equal false
if touching == true and... can be shortened to if touching and... unless you expect touching to be any random value and only want to do something if it's specifically true
- You don't want to be using variables like
grabbed to refer to things like a player's CashCollected, since this is a server script that needs to handle many players (if 2+ players try to touch the part at once, one player will be awarded the other player's money as well as his/her own). You should either use a dictionary to track all players's CashCollected objects or make it local to the function(s) that use it (passing it to other functions as needed). For the touching variable, you'll definitely need a dictionary for that one (the key is the player, the value is true or false -- be sure to set it to nil when a player leaves to prevent memory leaks)
- Variables should be local to the function they are used in; try to avoid sharing variables between functions (though you always need some and that's okay)
Improved code:
local players = game:GetService("Players")
local teams = game:GetService("Teams")
local rs = game:GetService("ReplicatedStorage")
local showgui = rs:FindFirstChild("ShowGui")
local touching = {}
local db = {}
local function mainLoop(player)
if db[player] then return end
db[player] = true
local hasDied = false
local con = player.Character.Humanoid.Died:Connect(function()
hasDied = true
end)
local grabbed = user:WaitForChild("CashCollected")
local robbing = player.Robbing
while wait(1) and not hasDied and grabbed.Value < 2500 do
if touching[player] and robbing.Value then
print("giving money")
grabbed.Value = grabbed.Value + 100
end
end
con:Disconnect()
db[player] = false
end
script.Parent.Touched:Connect(function(hit)
if hit.Parent:FindFirstChild("Humanoid") then
local plr = hit.Parent
user = players:GetPlayerFromCharacter(plr)
if user then
if user.Robbing.Value == true then
touching[user] = true
print("true")
if user.Team.Name == "Citizens" then
showgui:FireClient(user,"Show")
end
mainLoop(user)
end
end
end
end)
script.Parent.TouchEnded:Connect(function(hit)
if hit.Parent:FindFirstChild("Humanoid") then
user = players:GetPlayerFromCharacter(hit.Parent)
if user then
touching[user] = false
if user.Robbing.Value == true then
print("false")
end
end
end
end)
players.PlayerRemoving:Connect(function(player)
db[player] = nil
touching[player] = nil
end)
By the way, I'm unsure if TouchEnded is guaranteed to work (last time I checked it doesn't); you should periodically check the character's position to see if they've left the area (then do touching[player] = false if so). Also, if the player's arm briefly touches script.Parent (in addition to the torso), money will stop being awarded even if the player's torso is still touching it.
[Edit: DAsanicmaster's answer of checking the humanoid's health is definitely superior in this case, but I leave this answer here because everything else I said is still fine and sometimes you need to listen to an event instead of checking a value.]
3 comments
your variable indenting is interesting xd
sorry i was just trying something new lol wasn't sure if i was gonna stick with it though
To accept an answer there should be an "Accept Answer" button below the "Post a comment" box on the answer you wish to accept.