duplicate Awake() causing destroy - move fix for issues/2778 to second pass
Unity 2020.3.22f1
Please move the fix from issue 2778 to the second pass NetworkServer.SpawnObjects() -https://github.com/vis2k/Mirror/blob/b2ce3421e50dc6082d207febc703a60c7798d976/Assets/Mirror/Runtime/NetworkServer.cs#L1107-L1115
Upon upgrading mirror in my project to the latest version in the asset store I found that several of my objects were being destroyed and throwing an error as NetworkIdentity.Awake() was being called twice. I believe this is because on the first loop the parent object with network identity is still inactive when the child with the network identity is checked for !identity.gameObject.activeInHierarchy.
https://github.com/vis2k/Mirror/blob/b2ce3421e50dc6082d207febc703a60c7798d976/Assets/Mirror/Runtime/NetworkIdentity.cs#L325-L330
By moving this check to the second loop we ensure that all game objects will be set to active before we check to see if we need to manually call Awake().
For my project I have applied:
foreach (NetworkIdentity identity in identities)
{
if (ValidateSceneObject(identity))
{
// Debug.Log($"SpawnObjects sceneId:{identity.sceneId:X} name:{identity.gameObject.name}");
identity.gameObject.SetActive(true);
}
}
// second pass: initialize nested scene object if parent is inactive and spawn all scene objects
foreach (NetworkIdentity identity in identities)
{
// fix https://github.com/vis2k/Mirror/issues/2778:
// -> SetActive(true) does NOT call Awake() if the parent
// is inactive
// -> we need Awake() to initialize NetworkBehaviours[] etc.
// because our second pass below spawns and works with it
// => detect this situation and manually call Awake for
// proper initialization
if (ValidateSceneObject(identity))
{
if (!identity.gameObject.activeInHierarchy) {
//identity.Awake(); - See related issue below
identity.InitializeNetworkBehaviours();
}
Spawn(identity.gameObject);
}
}
More directly on the duplicate Awake() calls but slightly different - issues/2778 may need further review though its gone/archived and I do not see the original details at the link.
If the inactive object(s) that has already had its NetworkIdentity.Awake() called from this fix is then activated... it will also throw the error and be destroyed on this second Awake() call as hasSpawned will be true. - https://github.com/vis2k/Mirror/blob/b2ce3421e50dc6082d207febc703a60c7798d976/Assets/Mirror/Runtime/NetworkIdentity.cs#L325-L331
So instead of if (!identity.gameObject.activeInHierarchy) { identity.Awake(); }
possibly if (!identity.gameObject.activeInHierarchy) { identity.InitializeNetworkBehaviours(); }
Or similar method that calls InitializeNetworkBehaviours() and more if additional logic that must be separate from InitializeNetworkBehaviours() is required. Possibly also a different bool to ensure InitializeNetworkBehaviours() or the new method is bypassed on the potential future Awake() call when the object is activated.
This seems to still leave a gap on the client side for these same objects that are not initialized and another bit of logic may need to be added. Potentially to this loop - https://github.com/vis2k/Mirror/blob/b2ce3421e50dc6082d207febc703a60c7798d976/Assets/Mirror/Runtime/NetworkClient.cs#L1129-L1136
something similar to the final form of the above logic for the server or a dry shared method if that makes sense here...
foreach (NetworkIdentity identity in allIdentities)
{
// add all unspawned NetworkIdentities to spawnable objects
if (ConsiderForSpawning(identity))
{
spawnableObjects.Add(identity.sceneId, identity);
}
// initialize nested scene object if parent is inactive
if (NetworkServer.ValidateSceneObject(identity))
{
if (!identity.gameObject.activeInHierarchy) {
identity.InitializeNetworkBehaviours();
}
}
}
I applied these changes and have my project working again in the short term.
Thanks
thanks for details, gonna take a look
for reference. original issue: https://github.com/vis2k/Mirror/issues/2778 original fix: https://github.com/vis2k/Mirror/commit/2c2581fa08cc9f9611ac3ab8fbca73b3275e9e33
I know this post is old, but it just saved me today. Thank you.
will fix this soon, sorry for delay.
fixed. https://github.com/MirrorNetworking/Mirror/pull/3347