-
Notifications
You must be signed in to change notification settings - Fork 450
fix: In-scene NetworkObjects disabled but never re-enabled after scene transition #1354
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: In-scene NetworkObjects disabled but never re-enabled after scene transition #1354
Conversation
private TestingState m_TestingState; | ||
|
||
[UnityTest] | ||
public IEnumerator DDOLMoveAndRestoreInSceneNetworkObject() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't tell what this test does by its name.
I also can't really tell what the test does by looking at the test method. Is it testing that MoveObjectsToDontDestroyOnLoad
sets them to inactive? Is it testing that MoveObjectsFromDontDestroyOnLoadToScene
sets them to active? Is it testing both?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah... I need to come up with a better name for that test probably.
The test uses those two methods when doing a full scene transition (i.e. LoadSceneMode.Single).
- Pre-Scene Transition--> MoveObjectsToDontDestroyOnLoad (disables in-scene placed NOs in DDOL)
- Load Scene
- Post-Scene Transition--> MoveObjectsFromDontDestroyOnLoadToScene (enables in-scene placed NOs in DDOL)
I could just have easily manually disabled the NetworkObject and then just called the MoveObjectsFromDontDestroyOnLoadToScene method to validate the fix, but figured I might as well include the initial method that disables the in-scene placed NetworkObject (MoveObjectsToDontDestroyOnLoad) since that is what disables the NetworkObject(s) prior to doing the full scene transition.
@@ -1830,7 +1830,7 @@ internal void HandleSceneEvent(ulong clientId, FastBufferReader reader) | |||
/// Moves all NetworkObjects that don't have the <see cref="NetworkObject.DestroyWithScene"/> set to | |||
/// the "Do not destroy on load" scene. | |||
/// </summary> | |||
private void MoveObjectsToDontDestroyOnLoad() | |||
internal void MoveObjectsToDontDestroyOnLoad() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It appears that these are being made internal so that you can test them directly? This is a testing anti-pattern. To paraphrase a great number of testing authorities: "How do you test internals? Through the public API."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah... the test to validate this fix was a little tricky.
The only place the two methods pertaining to this bug and fix (MoveObjectsToDontDestroyOnLoad and MoveObjectsFromDontDestroyOnLoadToScene ) are called is when there is a full scene transition taking place. Since we cannot do a full scene transition (i.e. it would unload the Test Runner's temporary scene and would break the rest of the tests) in a unit and/or integration test, the only way to write a test (currently) to verify the fix in this PR was to create the same circumstances and call the same methods...which required them to be accessible.
If you want, I could reduce the anti-pattern footprint by just testing the MoveObjectsFromDontDestroyOnLoadToScene method and not including the MoveObjectsToDontDestroyOnLoad in that process (i.e. just disable it in the unit test itself).
|
||
public class ForcedInSceneBehaviour : NetworkBehaviour | ||
{ | ||
public event Action OnNetworkObjectSpawned; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: this event system to generic condition tracker feels like overkill. Why not just have an InSceneNetworkObjectDDOLTest
field on the network behaviour, assign it when you create it, and have it do something like InSceneNetworkObjectDDOLTest.OnEnabledWasCalled = true;
Then, in the test case, instead of the "waitforcondition" and "conditionmet(false)" stuff you can just do the waiting in-place and increase readability of the test:
while (!OnEnabledWasCalled)
{
yield return new WaitForSeconds(m_ConditionMetFrequency);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I could just do something like:
while (networkObject.isActiveAndEnabled)
{
yield return new WaitForSeconds(m_ConditionMetFrequency);
}
and to check it is re-enabled
while (!networkObject.isActiveAndEnabled)
{
yield return new WaitForSeconds(m_ConditionMetFrequency);
}
in place of the other stuff.
@@ -1916,6 +1916,8 @@ private void MoveObjectsFromDontDestroyOnLoadToScene(Scene scene) | |||
{ | |||
if (sobj.gameObject.scene == DontDestroyOnLoadScene && (sobj.IsSceneObject == null || sobj.IsSceneObject.Value)) | |||
{ | |||
// set in-scene placed NetworkObjects back to active | |||
sobj.gameObject.SetActive(true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this going to enabled objects which the user disabled manually?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe worth adding a few test cases:
- Scene-placed objects not in DDOL shouldn't be impacted
- Dynamic objects not in DDOL shouldn't be impacted
- Scene-placed objects in DDOL which are active should stay active
- Scene-Placed objects in DDOL which are inactive should stay inactive
- Dynamic objects in DDOL which are active shouldn't be impacted
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can do that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The most recent updated test includes the following test cases where all NetworkObjects' DestroyWithScene are set to false:
- Tests for both default enabled and disabled cases:
- Scene-placed NetworkObjects not already in the DDOL
- Dynamically spawned NetworkObjects not already in the DDOL
- Scene-placed NetworkObjects already in the DDOL
- Dynamically spawned NetworkObjects already in the DDOL
As a side note:
Both dynamically spawned and in-scene placed NetworkObjects that do not have the DestroyWithScene set to false will be despawned before the scene transition.
This now tracks the state of NetworkObjects when a full scene transition takes place. This includes a refactored test for NetworkObjects (dynamically spawned and in-scene placed) that persist a full scene transition.
This makes sure that DestroyWithScene is set to false for all InSceneNetworkObjectState tests.
Added entries for the fixes applied in this PR.
com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs
Outdated
Show resolved
Hide resolved
com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs
Outdated
Show resolved
Hide resolved
After peer review during PR Triage we all decided to not change or track a NetworkObject's parent GameObject's state and to not disable during full scene transition. Removed all active state tracking dictionaries and references as well as removed disabling DDOL migrated GameObjects from the runtime NGO code base. Adjusted the DDOL test to check the state is maintained throughout the scene transition. The DDOL test only required a minor
Updating the changelog to reflect most recent updates.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚀
|
…e transition (#1354) * fix This is the fix for the in-scene NetworkObjects moved into DDOL and the after a scene transition they become disabled but never re-enabled. * test Had to make some private methods internal for testing purposes. Adding test to validate the fix. * style white space fixes. * style Adding comment above the primary line of code that is the fix for this PR * style removing unused namespace. * style removing several LFs * fix and test This now tracks the state of NetworkObjects when a full scene transition takes place. This includes a refactored test for NetworkObjects (dynamically spawned and in-scene placed) that persist a full scene transition. * test update This makes sure that DestroyWithScene is set to false for all InSceneNetworkObjectState tests. * style Removing whitespace. * updated changelog Added entries for the fixes applied in this PR. * refactor After peer review during PR Triage we all decided to not change or track a NetworkObject's parent GameObject's state and to not disable during full scene transition. Removed all active state tracking dictionaries and references as well as removed disabling DDOL migrated GameObjects from the runtime NGO code base. Adjusted the DDOL test to check the state is maintained throughout the scene transition. The DDOL test only required a minor * updated changelog Updating the changelog to reflect most recent updates.
…e transition (#1354) (#1465) * fix This is the fix for the in-scene NetworkObjects moved into DDOL and the after a scene transition they become disabled but never re-enabled. * test Had to make some private methods internal for testing purposes. Adding test to validate the fix. * style white space fixes. * style Adding comment above the primary line of code that is the fix for this PR * style removing unused namespace. * style removing several LFs * fix and test This now tracks the state of NetworkObjects when a full scene transition takes place. This includes a refactored test for NetworkObjects (dynamically spawned and in-scene placed) that persist a full scene transition. * test update This makes sure that DestroyWithScene is set to false for all InSceneNetworkObjectState tests. * style Removing whitespace. * updated changelog Added entries for the fixes applied in this PR. * refactor After peer review during PR Triage we all decided to not change or track a NetworkObject's parent GameObject's state and to not disable during full scene transition. Removed all active state tracking dictionaries and references as well as removed disabling DDOL migrated GameObjects from the runtime NGO code base. Adjusted the DDOL test to check the state is maintained throughout the scene transition. The DDOL test only required a minor * updated changelog Updating the changelog to reflect most recent updates. Co-authored-by: Noel Stephens <noel.stephens@unity3d.com>
…e transition (Unity-Technologies#1354) * fix This is the fix for the in-scene NetworkObjects moved into DDOL and the after a scene transition they become disabled but never re-enabled. * test Had to make some private methods internal for testing purposes. Adding test to validate the fix. * style white space fixes. * style Adding comment above the primary line of code that is the fix for this PR * style removing unused namespace. * style removing several LFs * fix and test This now tracks the state of NetworkObjects when a full scene transition takes place. This includes a refactored test for NetworkObjects (dynamically spawned and in-scene placed) that persist a full scene transition. * test update This makes sure that DestroyWithScene is set to false for all InSceneNetworkObjectState tests. * style Removing whitespace. * updated changelog Added entries for the fixes applied in this PR. * refactor After peer review during PR Triage we all decided to not change or track a NetworkObject's parent GameObject's state and to not disable during full scene transition. Removed all active state tracking dictionaries and references as well as removed disabling DDOL migrated GameObjects from the runtime NGO code base. Adjusted the DDOL test to check the state is maintained throughout the scene transition. The DDOL test only required a minor * updated changelog Updating the changelog to reflect most recent updates.
…e transition (Unity-Technologies#1354) (Unity-Technologies#1465) * fix This is the fix for the in-scene NetworkObjects moved into DDOL and the after a scene transition they become disabled but never re-enabled. * test Had to make some private methods internal for testing purposes. Adding test to validate the fix. * style white space fixes. * style Adding comment above the primary line of code that is the fix for this PR * style removing unused namespace. * style removing several LFs * fix and test This now tracks the state of NetworkObjects when a full scene transition takes place. This includes a refactored test for NetworkObjects (dynamically spawned and in-scene placed) that persist a full scene transition. * test update This makes sure that DestroyWithScene is set to false for all InSceneNetworkObjectState tests. * style Removing whitespace. * updated changelog Added entries for the fixes applied in this PR. * refactor After peer review during PR Triage we all decided to not change or track a NetworkObject's parent GameObject's state and to not disable during full scene transition. Removed all active state tracking dictionaries and references as well as removed disabling DDOL migrated GameObjects from the runtime NGO code base. Adjusted the DDOL test to check the state is maintained throughout the scene transition. The DDOL test only required a minor * updated changelog Updating the changelog to reflect most recent updates. Co-authored-by: Noel Stephens <noel.stephens@unity3d.com>
Only when there is an in-scene placed NetworkObject that moves itself into the DDOL scene and there is a full scene transition (i.e. LoadSceneMode.Single) the in-scene placed NetworkObject will get disabled and never re-enabled.
This PR resolves the above issue.
MTT-1479
PR Checklist
type:backport-release-*
label. After you backport the PR, the label changes tostat:backported-release-*
.CHANGELOG.md
file.Changelog
com.unity.netcode.gameobjects
Testing and Documentation