Gate something on all players being ready
How to block an action until every present player has confirmed they're ready, using
AutoPlayerTracker to know who's present and
ReadyCheckProcess to track their ready state.
Steps
-
Declare a
[WirePool]field for each. Both ship as TsVRC's own default pool entries, so there's nothing to register on the Configure window first, and codegen callsTsConstructfor you at wire time:public class MatchStarter : TsBehaviour{[WirePool][SerializeField] private AutoPlayerTracker _roster;[WirePool][SerializeField] private ReadyCheckProcess _readyCheck;protected override void TsStart(){_roster.StartAutoTracking();_roster.TsSubscribe(this, AutoPlayerTracker.OnAutoTrackingPlayersAddedEvent, nameof(_OnRosterChanged));}public void _OnRosterChanged(){if (!_readyCheck.IsProcessRunning()){_readyCheck.StartReadyCheck(_roster.LastPlayerIds);}}} -
Subscribe to completion and act on it:
protected override void TsStart(){// ...continued from above_readyCheck.TsSubscribe(this, ReadyCheckProcess.OnReadyCheckCompletedEvent, nameof(_OnEveryoneReady));}public void _OnEveryoneReady() => StartMatch(); -
Wherever your own UI lets a player mark themselves ready, call
_readyCheck.SetReady()(orSetReady(false)to un-ready). Only the calling player's own status can be changed this way; see the reference page for why.
Handling the roster changing mid-check
If a player can join or leave while the check is already running, restart it with the
current roster rather than trying to patch the running one: ReadyCheckProcess doesn't
support adding players to a check already in progress.
public void _OnRosterChanged()
{
if (_readyCheck.IsProcessRunning())
{
_readyCheck.StopReadyCheck();
}
_readyCheck.StartReadyCheck(_roster.LastPlayerIds);
}
For a fixed, known set of players instead of "everyone currently in the instance," start
PlayerTracker/ReadyCheckProcess directly with that explicit ID list and skip
AutoPlayerTracker entirely.
Declare each [WirePool] field exactly once in the whole project if you want one shared
roster and ready check. Pool slot counts are computed per
type:
a second [WirePool] private ReadyCheckProcess field somewhere else allocates a second,
independent instance rather than sharing this one. Reach the same instance from another
behaviour with an ordinary serialized reference or a Global, not a second [WirePool]
field of the same type.
Why this shape
ReadyCheckProcess only tracks readiness for players it's already tracking. See
its reference page for the ordering guarantees
around SetReady and what happens when the tracked set changes mid-check. For the "why
generated code, why not just call these directly at compile time" background, see
How TsVRC fits together.