AutoPlayerTracker
Tsvrc.Tracking.AutoPlayerTracker is a PlayerTracker that tracks every player in
the instance, with no player list to manage. Its generated shadow is TsAutoPlayerTracker. See
Track a custom group of players for when to use it instead
of a plain PlayerTracker.
Getting an instance
AutoPlayerTracker is one of the builtin pool entries, so a
[WirePool] field of this type resolves with nothing to register, and codegen calls TsConstruct
on it. If you place the shipped AutoPlayerTracker prefab in your scene yourself instead, call
TsConstruct on it before using it.
Usage
Call StartAutoTracking(). It makes the calling player the owner first, so tracking runs on the
player who starts it. StartPlayerTracking is overridden to do the same as StartAutoTracking and
ignores both of its parameters, since AutoPlayerTracker never uses the process update.
StopAutoTracking() and CompleteAutoTracking() call StopPlayerTracking and
CompletePlayerTracking.
While tracking runs, the owner adds each player who joins in OnPlayerJoined. A join is skipped
when the player reference isn't valid,
which VRChat says to check before using a player. Players who leave or
are suspended are removed by the base class. Other players
ignore OnPlayerJoined,
because only the owner changes the tracked set.
public class InstanceRoster : TsBehaviour
{
[WirePool][SerializeField] private AutoPlayerTracker _tracker;
protected override void TsStart()
{
_tracker.TsSubscribe(this, AutoPlayerTracker.OnAutoTrackingPlayersAddedEvent, nameof(_OnRosterChanged));
_tracker.TsSubscribe(this, AutoPlayerTracker.OnAutoTrackingPlayersRemovedEvent, nameof(_OnRosterChanged));
_tracker.StartAutoTracking();
}
public void _OnRosterChanged() => LogInfo(_tracker.LastPlayerIds.Length + " players in the instance.");
}
When the first list is read
StartAutoTracking reads the player list when it's called, not in OnPlayerJoined. Joining an
instance fires OnPlayerJoined for every player already
present, the local
player included, and that wave fires before any of your code runs. The tracker isn't running yet,
so it drops all of those events, and the list read at start is what covers those players.
A player still joining at that moment fires OnPlayerJoined later, once tracking runs, and is added
then. UdonSharp runs on the Unity main thread only, so no OnPlayerJoined can run between reading
the list and the start of tracking, and no joining player is missed.
The first list leaves out players who are already suspended. The base class removes a player when they become suspended, so a player who is suspended before tracking starts would never be removed.
Events
The same six events as PlayerTracker, with an Auto prefix: OnAutoTrackingStarted, Stopped,
Completed, Deserialization, PlayersAdded and PlayersRemoved, each with an
OnAutoTracking*Event constant. Each one overrides the matching OnTracking* hook to emit the
renamed event. Read LastPlayerIds, LastAddedPlayerIds and LastRemovedPlayerIds as on
PlayerTracker.