Inactive NetworkIdentities don't get cleaned up
Describe the bug
I have multiple Networked Objects in a scene that start inactive. They might get enabled at some point, but it is equally possible that they stay inactive for as long as the scene is loaded and get destroyed when it is unloaded.
Unity does not call OnDestroy on GameObjects that have never been active.
The NetworkIdentity component writes itself into the static spawned dictionary in OnStartServer, which is called for inactive GameObjects. This leads to this dictionary being populated with destroyed objects and the next time a scene is loaded, the NetworkServer throws an exception in SpawnObserversForConnection.
Expected behavior
GameObjects that were never active should either not register themselves in the spawned dictionary, or get cleaned up properly when they get destroyed.
Desktop (please complete the following information):
- OS: Windows 10
- Build target: Windows Standalone
- Unity version: 2019.4.11f1
- Mirror branch: v26.2.2
As a first workaround I added the following to the NetworkIdentity:
private bool _initialized;
private void OnEnable() {
if (_initialized || !isServer) return;
spawned[netId] = this;
_initialized = true;
}
and I wrapped the spawned[netID] = this cal in OnStartServer like so:
if (gameObject.activeInHierarchy) {
spawned[netId] = this;
_initialized = true;
}
I haven't tested enough to know if this is always working correctly.
If this is still an issue I need steps to reproduce. I tried a few things and can't get it to fail.
To reproduce I just added a GameObject with a NetworkIdentity and a NetworkSceneChecker as a child to an Empty and disabled the parent object. As soon as I load that Scene and then load another Scene, I get a MissingReferenceException.
for future reference, might be related to https://github.com/vis2k/Mirror/issues/2119 which is currently being fixed