feat: Fix SyncList<NetworkIdentity/GameObject/NetworkBehaviour> fragility by caching network IDs
SyncVars of NetworkIdentity and other networked objects internally use a field of netId to make them resilient when interest management happens.
This prevents SyncVars of those types from being forever null when the object is hidden to clients.
SyncLists don't do such caching, so if an interest management happens and object gets hidden, SyncLists will point to null forever.
This PR implements same care to SyncLists by making clients store netIds and componentIndexes instead of direct references to those networked objects. (NetworkIdentity, GameObject, NetworkBehaviour)
What now works with this PR
class Monster : NetworkBehaviour { }
class Human : NetworkBehaviour
{
public readonly SyncList<Monster> pets = new SyncList<Monster>();
}
// ...
someHuman.pets.Add(rabbitMonster);
// ... Rabbit gets really far away and gets hidden
Debug.Log(someHuman.pets[0]); // is now null on client
// ... Rabbit gets closeby again
Debug.Log(someHuman.[0]); // points to rabbit again!
Caveats
- Some list operations are now a few lines longer, which will affect SyncList performance even non-networked object ones (although difference will be miniscule)
- This does nothing if said networked objects are inside structs. e.g.
SyncList<StructWithNetIdentityField>
Alternatives we could perhaps consider?
-
Leave SyncList alone, and add several special traited types of SyncList. e.g.
SyncListNetworkBehaviour<T> where T : NetworkBehaviourSyncListNetworkIdentitySyncListGameObjector maybe a single typeSyncListNetworkedObject<T>that supports caching ofNetworkIdentity,GameObject, andNetworkBehaviour -
Introduce
Syncable<T>and make users use them likeSyncList<Syncable<GameObject>>,SyncList<Syncable<Monster>>(requires Weaver work, as it can't generate readers/writers for generic types)
struct Syncable<T>
{
public Syncable(T original)
{
// Store relevant data of networked object (netId, componentIndex)
}
public T Get()
{
// Dereference back to networked object
}
}