Track a custom group of players
How to maintain a synced roster of players for something narrower than "everyone in the
instance", using PlayerTracker directly instead of
AutoPlayerTracker.
When to use which
Reach for AutoPlayerTracker first if the roster really is "every player currently in
the instance": it needs no add/remove calls of your own. Use a bare PlayerTracker
instead when the roster is a subset you decide, players entering a specific area,
opting into a queue, being invited to a team, since AutoPlayerTracker always tracks
everyone and can't be told to track less.
Steps
-
Declare a
[WirePool]field.PlayerTrackerships as one of TsVRC's own default pool entries, so there's nothing to register on the Configure window first:public class SpectatorRoster : TsBehaviour{[WirePool][SerializeField] private PlayerTracker _spectators;protected override void TsStart(){_spectators.TsSubscribe(this, PlayerTracker.OnTrackingPlayersAddedEvent, nameof(_OnRosterChanged));_spectators.TsSubscribe(this, PlayerTracker.OnTrackingPlayersRemovedEvent, nameof(_OnRosterChanged));_spectators.StartPlayerTracking(new string[0]);}public void _OnRosterChanged() => LogInfo(_spectators.LastPlayerIds.Length + " spectators.");} -
Add or remove players as your own logic decides, for example when a player enters or leaves a trigger volume:
public override void OnPlayerTriggerEnter(VRCPlayerApi player){_spectators.AddTrackedPlayers(new[] { TsPlayer.GetPlayerID(player) });}public override void OnPlayerTriggerExit(VRCPlayerApi player){_spectators.RemoveTrackedPlayers(new[] { TsPlayer.GetPlayerID(player) });}A player who leaves the instance or gets suspended is removed automatically; you never need to handle that yourself.
-
Read the roster from
LastPlayerIdsinside anyOnTracking*callback. It's a synced, owner-managed set: a non-owner'sAddTrackedPlayers/RemoveTrackedPlayerscalls forward to the current owner over the network rather than applying locally.
Why this shape
See PlayerTracker's reference page for the full
event table, exactly when a Notify* broadcast fires versus when LastPlayerIds itself
updates, and the three separate paths that remove a player automatically (leaving,
suspending, or the tracker's own owner abandoning it).