for i, player in pairs(game.ServerStorage.playersInRound:GetChildren()) do
character = game.Players:FindFirstChild(player.Name).Character
character.Humanoid:MoveTo((gameElevator.elevatorFloor.Position + Vector3.new(0, 0, 30)) + Vector3.new(math.random(-5, 5), 5, math.random(-5, 5)))
--separately (in a coroutine) enable player movement after the movement is completed
coroutine.wrap(function()
character.Humanoid.MoveToFinished:Wait()
game.ReplicatedStorage.controlsRemoteEvents.enableControls:FireClient(game.Players:FindFirstChild(player.Name))
end)()
end
--solidify elevator hitbox
gameElevator.elevatorHitbox.CanCollide = true
Essentially what’s happening is players on an elevator have their controls disabled, I move them all off the elevator at the same time, then solidify a hitbox so that the players cannot get back on the elevator (their movement is enabled again shortly after)
The thing is, I don’t want the for loop to wait on each player’s movement to complete before the next one can start. So, I used a coroutine.
However, when doing this, I found that because of the coroutine, when the last player is up, the loop ends because the coroutine is running separately and the rest of the script runs, meaning the hitbox is solidified when the last player is in it, glitching them through the floor.
My ideas for solutions:
-Add a wait (I don’t like this solution much, as it could be inconsistent)
-Instead of immediately starting the tween, do constant checks for players in a region3, and if there are no players, solidify hitbox and move on (fairly certain this will work, but I’d prefer something simpler, if possible (if not then I guess I can just use this))
By the way, you structured the code it will not wait till all players are done. So you can use a different technique but using the same code:
By giving it the max count of players and then counting each time the player gets their controls back it will solidify the hitbox once the Finished amount equals the Max count.
local Max = game.ServerStrorage.playersInRound:GetChildren()
local Finished = 0
for i, player in pairs(game.ServerStorage.playersInRound:GetChildren()) do
character = game.Players:FindFirstChild(player.Name).Character
character.Humanoid:MoveTo((gameElevator.elevatorFloor.Position + Vector3.new(0, 0, 30)) + Vector3.new(math.random(-5, 5), 5, math.random(-5, 5)))
--separately (in a coroutine) enable player movement after the movement is completed
coroutine.wrap(function()
character.Humanoid.MoveToFinished:Wait()
game.ReplicatedStorage.controlsRemoteEvents.enableControls:FireClient(game.Players:FindFirstChild(player.Name))
Finished += 1
end)()
end
--solidify elevator hitbox
repeat
wait()
until Finished == #Max
gameElevator.elevatorHitbox.CanCollide = true
local currentHumanoid = nil
for i, player in ipairs(game.ServerStorage.playersInRound:GetChildren()) do
character = player.Character
character.Humanoid:MoveTo((gameElevator.elevatorFloor.Position + Vector3.new(0, 0, 30)) + Vector3.new(math.random(-5, 5), 5, math.random(-5, 5)))
--separately (in a coroutine) enable player movement after the movement is completed
task.spawn(function()
currentHumanoid = character.Humanoid
character.Humanoid.MoveToFinished:Wait()
game.ReplicatedStorage.controlsRemoteEvents.enableControls:FireClient(game.Players:FindFirstChild(player.Name))
end)
end
if currentHumanoid.WalkToPoint then
currentHumanoid.MoveToFinished:Wait()
end
--solidify elevator hitbox
gameElevator.elevatorHitbox.CanCollide = true
ipairs being index-value pairs, right? so when using ipairs for an array its easier because its set up to be index value pairs already, contrary to a dictionary, where its key-value pairs?
Yes, exactly. To be honest though, it isn’t too much of a difference, so you shouldn’t worry about using the correct ones all the time (unless you want very specific micro-optimizations).