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 the Core 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 take it back). It only changes the status of the calling player, see the reference page for why.
Handling the roster changing mid-check
A player who leaves or is suspended is removed from the check automatically. To include a player who joins while the check runs, add them to it. They start out not ready:
public void _OnRosterChanged()
{
if (_readyCheck.IsProcessRunning())
{
_readyCheck.AddTrackedPlayers(_roster.LastAddedPlayerIds);
return;
}
_readyCheck.StartReadyCheck(_roster.LastPlayerIds);
}
Restarting the check with the current roster also works, but clears every ready mark.
For a fixed, known set of players instead of everyone in the instance, start the ready check with
that ID list and skip AutoPlayerTracker.
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
See the ReadyCheckProcess reference page for the
ordering of SetReady and what happens when the tracked set changes during a check. For the "why
generated code, why not just call these directly at compile time" background, see
How Core fits together.