As pointed out in many discussions on this forum:
The Verse “Agent.Respawn()” function is severely bugged and it will prevent many actions after a player’s been respawned using it.
I’ve been recently contacted by a creator which needed help because if a player’s been respawned using the Respawn() function, nobody can spectate him.
Instead of charging him for something Epic hasn’t been able to solve yet, here’s a my workaround everybody can use.
Island Settings
- Set Respawn Type to “Wave”, this is not strictly needed but it may be useful if all players are supposed to spawn at the same time
- Set “Only Allow Respawn if Spawn Pads Found” as true
- Set Spawn Limit off since we’ll need infinite respawns
- Set Respawn Time to “1.0”, which is the minimum you can set
- Set Override Spawn Immunity Time as true, and Spawn Immunity Time to “0.0”
Spawn Pads
- Add one or more Spawn Pad for each team you’ll have in your game.
- If your gamemode is based on teams (like 2v2 for example) remember to add the right amount of pads for each team.
- Leave their settings as default, but change the Team Index
Creative Device (Verse)
instant_respawn_device := class(creative_device):
@editable
RespawnTrigger : trigger_device = trigger_device{}
@editable
PlayerSpawnDevices : []player_spawner_device = array{}
<# Standard OnBegin event #>
OnBegin<override>()<suspends>:void=
# Exposing the "RespawnAll" event with a trigger device, replace this with your own method or just call it using Verse
RespawnTrigger.TriggeredEvent.Subscribe(RespawnAll)
Sleep(1.0)
for(SpawnDev : PlayerSpawnDevices):
SpawnDev.SpawnedEvent.Subscribe(AgentRespawned)
# Disable all respawns (the function is including a 1 sec delay, so all the initial player are spawned correctly when the game starts)
DisableRespawns()
<# Used to subscribe the actual RespawnAll function, which is async #>
RespawnAll<public>(MaybeAgent : ?agent):void=
spawn{PostRespawnAll()}
<# Respawn process #>
PostRespawnAll<public>()<suspends>:void=
Sleep(1.0)
# Enable all the spawnpads
for(SpawnDev : PlayerSpawnDevices):
SpawnDev.Enable()
# Check each player present in the game
for(Player : GetPlayspace().GetPlayers(), not Player.GetFortCharacter[].IsActive[]):
# Respawn the player somewhere, it's not important since it will get eliminated and respawned on an actual pad
Player.Respawn(vector3{Z := 512.0}, rotation{})
# Wait
Sleep(0.01)
# Eliminate the player's character once again, this will trigger the automatic respawn action on those pads we've just enabled
if(PChar := Player.GetFortCharacter[]):
PChar.SetVulnerability(true)
Sleep(0.01)
PChar.Damage(damage_args{Amount := 999999999.0, Instigator := option{PChar}, Source := option{PChar}})
<# Each time someone respawns, check if pads can be disabled #>
AgentRespawned(Agent : agent):void=
var bCanDisableSpawnPads : logic = true
for(Player : GetPlayspace().GetPlayers(), not Player.GetFortCharacter[].IsActive[]):
set bCanDisableSpawnPads = false
if(bCanDisableSpawnPads?):
DisableRespawns()
<# Disable all pads #>
DisableRespawns<public>():void=
# Disable all the pads in use
for(SpawnDev : PlayerSpawnDevices):
SpawnDev.Disable()
After building the Verse code, add the device into your scene and make sure to all your Spawn Pads to its list.
Considerations
Elimination count
Since this process will force respawn by spawning and eliminating the player, you should consider this step if you have something like a ranking system, or an “Eliminated” tracker device, so make sure to remove 1 “Eliminated” count each time you use it.
Double elimination on screen
Looking at the result, it’s pretty obvious that the player’s being eliminated and then respawned. You can mask the process, for example, by adding a black screen while the function is doing its things.
Further improvements
This is the generic solution you might want to use, but there’s still room for improvements and adaptations depending on your project setup.
Result
Contacts
If you’ve found this workaround useful, consider following me on 𝕏: @kliansenpai