So, I have found this really irritating bug that that stops my teleport script from working how it should, I believe I know what would fix it but i’m not sure how to approach it… Here’s the function:
--[ loops through all players in the game, gets their character and teleports them to the spawnpad on the map... ]--
--[ ISSUE: when the player dies before this function runs, it doesn't teleport as the script wasn't able to find their character (since they're dead) ]--
function TeleportPlayers(spawnPad)
for _, plr in pairs(Players:GetChildren()) do
local character = plr.Character or plr.CharacterAdded:Wait()
if character and character.Parent then
character:PivotTo(spawnPad.CFrame * CFrame.new(0, 5, 0))
print("teleporting "..plr.Name.." to map")
else
warn("could not find "..plr.Name.." character")
end
end
end
ISSUE:
The issue is as i described in the comment of the code… i just need a way to repeat searching for the Players new Character to then assign the variable to and teleport them.
EXTRA:
I’ve been scavenging the internet for like 4 hours just hoping someone had found a solution but unfortunately not…
function TeleportPlayers(spawnPad)
for _, plr in pairs(Players:GetPlayers()) do
local character = plr.Character or plr.CharacterAdded:Wait()
if character and character.Parent then
character:PivotTo(spawnPad.CFrame + CFrame.new(0, 5, 0))
print("teleporting "..plr.Name.." to map")
else
repeat wait() until plr.Character -- This will wait() until plr.Character is found
end
end
end
2 things i noticed the first thing is that this might be intentional or i just dont fully understand the script but at line 9 yout multiplying the new spawn pads position by 0,5,0 this could pose a problem because 0 x anything is 0 that would eliminate the x and y cords and leave the y cord(up and down) second thing there is a function not sure if this is what you need but it might provide a lead Its called character appearance loaded there is also character loaded
Hope this helps if this doesent help let me know bc i might have more ideas
Ps sorry for typos im on mobile and sorry for grammar and punctuation stuff im dislexic
the PivotTo(____ * CFrame.new(0, 5, 0)) is just teleporting the player +5 studs above the SpawnPad to stop any weird bugs with the Character, I’ll try out that AppearanceLoaded function and let you know!
I think he was just recommending to not multiply. If you want to move the player upwards by 5 studs, just add the CFrame instead. PivotTo(____ + CFrame.new(0, 5, 0))
I tried this out and unfortunately it doesn’t work, honestly it made a lot of sense to use a repeat loop but nothing changed, when the Player dies before teleporting it respawns them in the default spawn rather than on the map…
Maybe this? I think it should yield and wait until the character is found.
function TeleportPlayers(spawnPad)
for _, plr in pairs(Players:GetPlayers()) do
local character = plr.Character or plr.CharacterAdded:Wait()
if not plr.Character then repeat wait() until plr.Character
if character and character.Parent then
character:PivotTo(spawnPad.CFrame + CFrame.new(0, 5, 0))
print("teleporting "..plr.Name.." to map")
end
end
end
Found something! Woulf player.respawnlocation work! If you change the respon location every time the player dies! If your trying to make it respawn at a random spawn location you could do somthing like check the humanoids health every time its changed then if its 0 set the respawn location to a random 1 across the game this would be done across the server you also would have to set it random when the player joins this would spawn the player at the original spawn location then immediately set its new spawn location to a new place when the player dies it will respawn it a said respawn location and then pick a new random respawn location…
Check the properties of the respawn pad and see if there is somthing like spawn here on default anf de check that
I was just messing around with repeat loops and managed to make it work like this:
function TeleportPlayers(spawnPad)
for _, plr in pairs(Players:GetPlayers()) do
local humanoidRootPart = plr.Character:WaitForChild("HumanoidRootPart", 1)
if humanoidRootPart then
print("found rootpart, player is alive")
local character = plr.Character or plr.CharacterAdded:Wait()
if character and character.Parent then
character:PivotTo(spawnPad.CFrame * CFrame.new(0, 5, 0))
print("teleporting "..plr.Name.." to map")
end
else
repeat
print("waiting for player to respawn")
wait(0.25)
until plr.Character:FindFirstChild("HumanoidRootPart")
plr.Character:PivotTo(spawnPad.CFrame * CFrame.new(0, 5, 0))
print("teleporting "..plr.Name.." to map")
end
end
end
I would not recommend polling (repeatedly waiting and checking in a loop) when you can use events. I would suggest the following code as an alternative solution (I haven’t tested whether it works, though). Some checks in isCharacterAlright may be unnecessary, you could remove some if you want and only keep the ones you think are needed.
Your current code may give errors which is another thing I would recommend you to avoid. If plr.Character is nil when TeleportPlayers is called (which is the case if the player has just joined), your code will give an error ‘Attempt to index nil with WaitForChild’. I’m also not sure if your code will actually always work even in cases where it doesn’t throw an error. I mean, the HumanoidRootPart’s existence doesn’t tell whether the Humanoid is alive.
As you can see, I added some code for preventing memory leaks. Storing the connection also allows disconnecting it if it’s possible that something changes such that teleporting to the map should no longer be allowed. In such a case, you could just disconnect the connection.
local Players = game:GetService("Players")
-- The purpose of this is to store connections so that they can be disconnected when the player leaves.
local characterAddedConns = {}
local function teleportCharacter(character, spawnPad)
character:PivotTo(spawnPad.CFrame * CFrame.new(0, 5, 0))
print("teleporting "..character.Name.." to map")
end
local function isCharacterAlright(character)
if character == nil then
return false
end
if character.Parent == nil then
return false
end
if character:FindFirstChild("HumanoidRootPart") == nil then
return false
end
local humanoid = character:FindFirstChild("Humanoid")
if humanoid == nil then
return false
end
if humanoid.Health == 0 then
return false
end
return true
end
function TeleportPlayers(spawnPad)
for _, plr in pairs(Players:GetChildren()) do
local currentCharacter = plr.Character
print(isCharacterAlright(currentCharacter))
if not isCharacterAlright(currentCharacter) then
warn(plr.Name.." character cannot be teleported at the moment.")
-- Using :Once instead of :Connect causes the connection to be disconnected when CharacterAdded fires next time.
-- Without it, the connection would have to be disconnected in the connected function when it's only needed once.
characterAddedConns[plr] = plr.CharacterAdded:Once(function(newCharacter)
teleportCharacter(newCharacter, spawnPad)
end)
else
teleportCharacter(currentCharacter, spawnPad)
end
end
end
local function onPlayerRemoving(plr)
-- These lines of code are for preventing memory leaks caused by connections that are no longer needed.
-- Disconnecting here is only needed if the player leaves before respawning. If the player leaves
-- while their character is alive, the connection has already been disconnected, but calling :Disconnect again
-- doesn't cause any problems. Removing the connection from the table is necessary regardless of whether the character
-- is alive when the player leaves.
if characterAddedConns[plr] ~= nil then
characterAddedConns[plr]:Disconnect()
characterAddedConns[plr] = nil
end
end
Players.PlayerRemoving:Connect(onPlayerRemoving)