FirstGearGames / FishNet

FishNet: Unity Networking Evolved.
Other
1.36k stars 146 forks source link

NetworkObjects of deleted GameObjects still being referenced in Observer Code #803

Open Shane-SDK opened 10 hours ago

Shane-SDK commented 10 hours ago

General Unity version: 2023.2.20f1 Fish-Networking version: 4.5.2R Discord link: Message

Description NetworkObjects that are spawned at runtime are not being cleaned up properly between scene loads.

Specifically old GameObjects which were deleted between scene loads still have their NetworkObject references in the nobCache retrieved by CollectionCaches.RetrieveList() (ServerObjects.Observers.cs - Line 342) when rebuilding observers. (In 2nd screenshot)

This behavior happens both for Host/Non-host network connections. This also only occurs for NetworkObjects which were spawned at runtime using ServerManager.Spawn(...). This hasn't happened for scene NetworkObjects. I've also tried the various scene loading methods such as loading Globally, loading using the Fish SceneManager API, as well as loading/unloading the scenes with Unity's SceneManagement API manually. The behavior is present with all three methods.

In my setup I spawn a NetworkObject immediately on Scene load, at some point a NetworkConnection will load the scene, therefore loading the runtime-spawned NetworkObject. This isn't a problem for the first scene load, but if I repeat the process the old NetworkObject will still be referenced, despite no longer having an underlying GameObject, as per the prior scene unload.

I've tested this on a few releases 4.5.2R - Bug exists 4.5.1R - Bug exists 4.5.0R - No bug, works as intended 4.4.6R - No bug, works as intended

Replication Steps to reproduce the behavior:

  1. Load a scene on the server, then spawn a Network GameObject at runtime.
  2. Load a new scene on the server, ensure old scene is unloaded
  3. Add a NetworkConnection to the new scene
  4. Server will rebuild observers using the old NetworkObject spawned in the first step, for the NetworkConnection. During this process it will access members of it's GameObject, which no longer exists

Expected behavior The nobCache shouldn't contain NetworkObjects whose GameObject was removed, as the function accesses members of the null GameObject through the NetworkObject.

Screenshots Immediate exception being raised image

The NetworkObjects being evaluated in observer code image

FirstGearGames commented 8 hours ago

Can you make a repo of this please. There was definitely a release where this was fixed but might be another condition elsewhere.

On Tue, Oct 29, 2024, 3:24 PM Shane @.***> wrote:

General Unity version: 2023.2.20f1 Fish-Networking version: 4.5.2R Discord link: Message https://discord.com/channels/424284635074134018/1034477094731784302/1300560688673980416

Description NetworkObjects that are spawned at runtime are not being cleaned up properly between scene loads.

Specifically old GameObjects which were deleted between scene loads still have their NetworkObject references in the nobCache retrieved by CollectionCaches.RetrieveList() (ServerObjects.Observers.cs - Line 342) when rebuilding observers. (In 2nd screenshot)

This behavior happens both for Host/Non-host network connections. This also only occurs for NetworkObjects which were spawned at runtime using ServerManager.Spawn(...). This hasn't happened for SceneObjects. I've also tried the various scene loading methods such as loading Globally, loading using the Fish SceneManager API, as well as loading/unloading the scenes with Unity's SceneManagement API manually. The behavior is present with all three methods.

In my setup I spawn a NetworkObject immediately on Scene load, at some point a NetworkConnection will load the scene, therefore loading the runtime-spawned NetworkObject. This isn't a problem for the first scene load, but if I repeat the process the old NetworkObject will still be referenced, despite no longer having an underlying GameObject, as per the prior scene unload.

I've tested this on a few releases 4.5.2R - Bug exists 4.5.1R - Bug exists 4.5.0R - No bug, works as intended 4.4.6R - No bug, works as intended

Replication Steps to reproduce the behavior:

  1. Load a scene on the server, then spawn a Network GameObject at runtime.
  2. Load a new scene on the server, ensure old scene is unloaded
  3. Add a NetworkConnection to the new scene
  4. Server will rebuild observers using the old NetworkObject spawned in the first step, for the NetworkConnection. During this process it will access members of it's GameObject, which no longer exists

Expected behavior The nobCache shouldn't contain NetworkObjects whose GameObject was removed, as the function accesses members of the null GameObject through the NetworkObject.

Screenshots Immediate exception being raised image.png (view on web) https://github.com/user-attachments/assets/4eac81d4-5a07-40ea-9366-f3440e13de50

The NetworkObjects being evaluated in observer code image.png (view on web) https://github.com/user-attachments/assets/70e93708-4c2a-4a5b-89ce-a7f629f46f24

— Reply to this email directly, view it on GitHub https://github.com/FirstGearGames/FishNet/issues/803, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGPJC3S2ZDRPJ7K42DMDRATZ57OIRAVCNFSM6AAAAABQ2SUGMKVHI2DSMVQWIX3LMV43ASLTON2WKOZSGYZDEMJTGU2TSNQ . You are receiving this because you are subscribed to this thread.Message ID: @.***>

FirstGearGames commented 8 hours ago

By repo I mean a unity package containing the bug. Please see our creating a bug report docs.

On Tue, Oct 29, 2024, 4:59 PM Ben Daigle @.***> wrote:

Can you make a repo of this please. There was definitely a release where this was fixed but might be another condition elsewhere.

On Tue, Oct 29, 2024, 3:24 PM Shane @.***> wrote:

General Unity version: 2023.2.20f1 Fish-Networking version: 4.5.2R Discord link: Message https://discord.com/channels/424284635074134018/1034477094731784302/1300560688673980416

Description NetworkObjects that are spawned at runtime are not being cleaned up properly between scene loads.

Specifically old GameObjects which were deleted between scene loads still have their NetworkObject references in the nobCache retrieved by CollectionCaches.RetrieveList() (ServerObjects.Observers.cs - Line 342) when rebuilding observers. (In 2nd screenshot)

This behavior happens both for Host/Non-host network connections. This also only occurs for NetworkObjects which were spawned at runtime using ServerManager.Spawn(...). This hasn't happened for SceneObjects. I've also tried the various scene loading methods such as loading Globally, loading using the Fish SceneManager API, as well as loading/unloading the scenes with Unity's SceneManagement API manually. The behavior is present with all three methods.

In my setup I spawn a NetworkObject immediately on Scene load, at some point a NetworkConnection will load the scene, therefore loading the runtime-spawned NetworkObject. This isn't a problem for the first scene load, but if I repeat the process the old NetworkObject will still be referenced, despite no longer having an underlying GameObject, as per the prior scene unload.

I've tested this on a few releases 4.5.2R - Bug exists 4.5.1R - Bug exists 4.5.0R - No bug, works as intended 4.4.6R - No bug, works as intended

Replication Steps to reproduce the behavior:

  1. Load a scene on the server, then spawn a Network GameObject at runtime.
  2. Load a new scene on the server, ensure old scene is unloaded
  3. Add a NetworkConnection to the new scene
  4. Server will rebuild observers using the old NetworkObject spawned in the first step, for the NetworkConnection. During this process it will access members of it's GameObject, which no longer exists

Expected behavior The nobCache shouldn't contain NetworkObjects whose GameObject was removed, as the function accesses members of the null GameObject through the NetworkObject.

Screenshots Immediate exception being raised image.png (view on web) https://github.com/user-attachments/assets/4eac81d4-5a07-40ea-9366-f3440e13de50

The NetworkObjects being evaluated in observer code image.png (view on web) https://github.com/user-attachments/assets/70e93708-4c2a-4a5b-89ce-a7f629f46f24

— Reply to this email directly, view it on GitHub https://github.com/FirstGearGames/FishNet/issues/803, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGPJC3S2ZDRPJ7K42DMDRATZ57OIRAVCNFSM6AAAAABQ2SUGMKVHI2DSMVQWIX3LMV43ASLTON2WKOZSGYZDEMJTGU2TSNQ . You are receiving this because you are subscribed to this thread.Message ID: @.***>

Shane-SDK commented 6 hours ago

I made the simplest recreation of what is happening in my project. Unfortunately the exact location of this exception is different, however it still revolves around NetworkObjects with no GameObject being referenced. Hopefully they are rooted in the same issue.

Tested with Unity 2023.2.20f1 4.5.2R - Error occurs 4.5.0R - Error does not occur

Once imported, open Assets/Init - OPEN ME and start the scene. GUI buttons will appear Click Begin Host then click Load Scene2 then click Scene1 UnityEngine.MissingReferenceException should be raised in SceneManager.cs - Line 1640

FishNet_Issue_803.zip

exception

Zelacks commented 3 hours ago

Ive been debugging this, I hope I am not out of line but, I think I found the cause. image This variable guards against despawning objects that have not been initialised inside OnDestroy. It gets set on prefabs (usually) when playmode starts. image

BUT, instantiated prefabs do not copy over the _initalizedValusSet since it non-serialized. So destroy code is not being called on spawned instantiated prefabs

Not saying this is the FIX, but the errors in my project go away when removing the if _initalizedValusSet return line from the destroy block, so im pretty certain this is the cause.