Answered by
5 years ago Edited 5 years ago
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:
01 | local players = game:GetService( "Players" ) |
02 | local teams = game:GetService( "Teams" ) |
03 | local rs = game:GetService( "ReplicatedStorage" ) |
04 | local showgui = rs:FindFirstChild( "ShowGui" ) |
08 | local function mainLoop(player) |
09 | if db [ player ] then return end |
12 | local con = player.Character.Humanoid.Died:Connect( function () |
15 | local grabbed = user:WaitForChild( "CashCollected" ) |
16 | local robbing = player.Robbing |
17 | while wait( 1 ) and not hasDied and grabbed.Value < 2500 do |
18 | if touching [ player ] and robbing.Value then |
20 | grabbed.Value = grabbed.Value + 100 |
27 | script.Parent.Touched:Connect( function (hit) |
28 | if hit.Parent:FindFirstChild( "Humanoid" ) then |
29 | local plr = hit.Parent |
30 | user = players:GetPlayerFromCharacter(plr) |
32 | if user.Robbing.Value = = true then |
35 | if user.Team.Name = = "Citizens" then |
36 | showgui:FireClient(user, "Show" ) |
44 | script.Parent.TouchEnded:Connect( function (hit) |
45 | if hit.Parent:FindFirstChild( "Humanoid" ) then |
46 | user = players:GetPlayerFromCharacter(hit.Parent) |
48 | touching [ user ] = false |
49 | if user.Robbing.Value = = true then |
56 | players.PlayerRemoving:Connect( function (player) |
59 | touching [ player ] = nil |
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.]