Hello fellow developers,
Recently i’ve been having an issue with my tower defense’s game PVP elevators that teleport you to an in-game match and i can’t seem to find out what’s causing it: Players enter elevators and are teleported flawlessly, but the problem comes when leaving an elevator with more than 1 player.
Supposing there’s 2 players in an elevator (A and B), player A can leave the elevator without an issue, but then when player B tries to, the UI button used to leave simply dissapears without doing anything else, leaving player B stuck in the elevator until someone else (either player A or anyone else) enters the same elevator, which then actually runs the leaving function for player B. No errors seem to appear in output, which only confuses me more. Does anyone know what the problem is here?
Elevators main code
--Only focus in 1v1 related code, 2v2 isn't finished yet.
local Functions = {}
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PVP_folder = workspace:WaitForChild("PVP")
local Elevators = PVP_folder:WaitForChild("Elevators")
local one = Elevators:WaitForChild("1V1")
local two = Elevators:WaitForChild("2V2")
local ElevatorNamesData = require(script.Parent.TextColors)
local leaveGuiEvent = ReplicatedStorage:WaitForChild("LeaveGuiEvent")
local PvpData = require(script.Parent:WaitForChild("PvpData"))
local ElevatorFunctions = require(script.Parent:WaitForChild("ElevatorFunctions"))
local function tableAmount(player1:Player?, player2:Player?)
local Table = {}
if player1 then
table.insert(Table, player1)
end
if player2 then
table.insert(Table, player2)
end
return Table
end
function Functions.updateBillboard(model:Instance?, playerCount:number?, countdown:number?, status:String?)
assert(model or playerCount or countdown or model:FindFirstChild("Billboards") or status, "something is nil")
local Billboard = model:FindFirstChild("Billboards").GuiPart
Billboard.SurfaceGui.Frame.players.Text = tostring(playerCount)
Billboard.SurfaceGui.Frame.time.Text = tostring(countdown)
Billboard.SurfaceGui.Frame.Status.Text = tostring(status)
end
function Functions.GetElevatorType(elevator)
if PvpData["1V1"][elevator] then
return "1v1"
elseif PvpData["2V2"][elevator] then
return "2v2"
else
return "Failed to get type"
end
end
function Functions.CanStart(data, Type)
if Type == "1v1" then
if data.Red and data.Blue then
return true
end
return false
elseif type == "2v2" then
local required = data.MaxSize
for index, teamData in pairs(data) do
if #teamData < required then
return false
end
end
return true
end
end
function Functions.CanJoin(player:Player, team:StringValue, data, two:BoolValue)
if two then
for i,v in pairs(data) do
if i ~= team and typeof(v) == "table" then
if table.find(v, player) then
return false
end
end
end
return true
end
for i, v in pairs(data) do
if i == team then
continue
end
if v == player then
return false
end
end
return true
end
function Functions.OneVone(player, hit, elevator, Team)
local data = PvpData["1V1"][elevator]
local canJoin = Functions.CanJoin(player, Team, data)
local team = nil
if data[Team] == nil and canJoin then
data[Team] = player
team = data[Team]
hit.Parent:MoveTo(elevator[Team .. "Part"]:GetChildren()[1].Position +Vector3.new(0,2,0))
else
return
end
local canStart = Functions.CanStart(data, "1v1")
leaveGuiEvent:FireClient(player)
leaveGuiEvent.OnServerEvent:Once(function(p)
for index, d in pairs(data) do
print(index, d)
if d == p then
data[index]=nil
print("Found and removed")
break
end
end
p.Character:MoveTo(elevator.LeavePos.Value)
Functions.updateBillboard(elevator, #tableAmount(data.Red, data.Blue), 0, "")
end)
if canStart then
for i = 10, 1, -1 do
data = PvpData["1V1"][elevator]
canStart = Functions.CanStart(data, "1v1")
if not canStart then
break
end
Functions.updateBillboard(elevator, #tableAmount(data.Red, data.Blue), i, "Countdown")
task.wait(1)
end
canStart = Functions.CanStart(data, "1v1")
if not canStart then
return
end
ElevatorFunctions.Teleport_Players({data.Red, data.Blue}, 10433192845, {team = Team, Map =elevator:GetAttribute("Map")})
data.Blue = nil
data.Red = nil
else
Functions.updateBillboard(elevator, 1, 0, "")
return
end
end
function Functions.table(table1:Table?, table2:Table?)
return #table1 + #table2
end
function Functions.twoVtwo(player, character, elevator, team)
local data = PvpData["2V2"][elevator]
local MaxSize = data.MaxSize
local SelectedTable = data[team]
if #SelectedTable < MaxSize and not table.find(SelectedTable, player) and Functions.CanJoin(player, team, data, true) then
table.insert(SelectedTable, player)
print("Added player")
local canStart = Functions.CanStart(data, "2v2")
leaveGuiEvent:FireClient(player)
if canStart then
for i =10, 1, -1 do
canStart = Functions.CanStart(data, "2v2")
if not canStart then
break
end
Functions.updateBillboard(elevator, Functions.table(data.Red, data.Blue), i, "Countdown")
end
end
else
return
end
end
function Functions.HandleTouch(hit, elevator, Team)
local player = Players:GetPlayerFromCharacter(hit.Parent)
if not player then return end
local Type = Functions.GetElevatorType(elevator)
if Type == "1v1" then
task.spawn(Functions.OneVone, player, hit, elevator, Team)
elseif Type == "2v2" then
Functions.twoVtwo(player, hit.Parent, elevator, Team)
end
end
for index, elevator in pairs(one:GetChildren()) do
if not elevator:FindFirstChild("Hitboxes") then
warn(elevator.Name .. " does not have a hitbox")
continue
end
elevator.Billboards.MapName.BillboardGui.Frame.TextLabel.Text = ElevatorNamesData[elevator.Name].Text
elevator.Billboards.MapName.BillboardGui.Frame.TextLabel.TextColor3 = ElevatorNamesData[elevator.Name].TextColor3
elevator.LeavePos.Value = elevator.Leaver.Position
elevator.Hitboxes.Blue.Touched:Connect(function(hit)
Functions.HandleTouch(hit, elevator, tostring(elevator.Hitboxes.Blue))
end)
elevator.Hitboxes.Red.Touched:Connect(function(hit)
Functions.HandleTouch(hit, elevator, tostring(elevator.Hitboxes.Red))
end)
end
for index, elevator in pairs(two:GetChildren()) do
if not elevator:FindFirstChild("Hitboxes") then
warn(elevator.Name .. " does not have a hitbox")
continue
end
--elevator.Billboards.MapName.BillboardGui.Frame.TextLabel.Text = ElevatorNamesData[elevator.Name].Text
--elevator.Billboards.MapName.BillboardGui.Frame.TextLabel.TextColor3 = ElevatorNamesData[elevator.Name].TextColor3
--elevator.LeavePos.Value = elevator.Leaver.Position
elevator.Hitboxes.Blue.Touched:Connect(function(hit)
Functions.HandleTouch(hit, elevator, tostring(elevator.Hitboxes.Blue))
end)
elevator.Hitboxes.Red.Touched:Connect(function(hit)
Functions.HandleTouch(hit, elevator, tostring(elevator.Hitboxes.Red))
end)
end
return Functions
Leaving button code
local leaveGuiEvent = game.ReplicatedStorage.LeaveGuiEvent
local player = game.Players.LocalPlayer
leaveGuiEvent.OnClientEvent:Connect(function()
player.PlayerGui.MainGui.leaveButton.Visible = true
end)
player.PlayerGui.MainGui.leaveButton.Activated:connect(function()
leaveGuiEvent:FireServer()
player.PlayerGui.MainGui.leaveButton.Visible = false
end)
PVP Data script
return {
["1V1"] = {},
["2V2"] = {}
}
Data setup script
local data = require(script.Parent:WaitForChild("PvpData"))
local oneVone = workspace:WaitForChild("PVP"):WaitForChild("Elevators"):WaitForChild("1V1")
local twoVtwo = workspace:WaitForChild("PVP"):WaitForChild("Elevators"):WaitForChild("2V2")
for index, map in pairs(oneVone:GetChildren()) do
data["1V1"][map] = {
}
end
for index, map in pairs(twoVtwo:GetChildren()) do
data["2V2"][map] = {
["Red"] = {},
["Blue"] = {},
MaxSize = 2
}
end
print(data)
require(script.Parent:WaitForChild("PvpModule"))
Thanks for reading!