Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions com.unity.netcode.gameobjects/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Additional documentation and release notes are available at [Multiplayer Documen

### Changed

- Updating usage of deprecated FindObjectsByType(FindObjectsSortMode) and enum FindObjectSortMode in 6000.4 and 6000.5. (#3857)
- Ensure logs in `NetworkObject` log the `NetworkObject.name` wherever possible. (#3831)
- Improved performance of NetworkBehaviour ILPostProcessor by omitting unnecessary type and assembly resolutions. (#3827)
- Improve performance of `NetworkObject`. (#3820, #3831)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ private static void ScenesInBuildActiveSceneCheck()
var activeScene = SceneManager.GetActiveScene();
var isSceneInBuildSettings = scenesList.Count((c) => c.path == activeScene.path) == 1;
#if UNITY_2023_1_OR_NEWER
var networkManager = Object.FindFirstObjectByType<NetworkManager>();
var networkManager = Object.FindAnyObjectByType<NetworkManager>();
#else
var networkManager = Object.FindObjectOfType<NetworkManager>();
#endif
Expand Down
41 changes: 41 additions & 0 deletions com.unity.netcode.gameobjects/Runtime/Core/FindObjects.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#if NGO_FINDOBJECTS_NOSORTING
using System;
#endif
using System.Runtime.CompilerServices;
using Object = UnityEngine.Object;

namespace Unity.Netcode
{
/// <summary>
/// Helper class to handle the variations of FindObjectsByType.
/// </summary>
/// <remarks>
/// It is intentional that we do not include the UnityEngine namespace in order to avoid
/// over-complicatd define wrapping between versions that do or don't support FindObjectsSortMode.
/// </remarks>
internal static class FindObjects
{
/// <summary>
/// Replaces <see cref="Object.FindObjectsByType"/> to have one place where these changes are applied.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="includeInactive">When true, inactive objects will be included.</param>
/// <param name="orderByIdentifier">When true, the array returned will be sorted by identifier.</param>
/// <returns>Resulst as an <see cref="Array"/> of type T</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T[] ByType<T>(bool includeInactive = false, bool orderByIdentifier = false) where T : Object
{
var inactive = includeInactive ? UnityEngine.FindObjectsInactive.Include : UnityEngine.FindObjectsInactive.Exclude;
#if NGO_FINDOBJECTS_NOSORTING
var results = Object.FindObjectsByType<T>(inactive);
if (orderByIdentifier)
{
Array.Sort(results, (a, b) => a.GetEntityId().CompareTo(b.GetEntityId()));
}
#else
var results = Object.FindObjectsByType<T>(inactive, orderByIdentifier ? UnityEngine.FindObjectsSortMode.InstanceID : UnityEngine.FindObjectsSortMode.None);
#endif
return results;
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -2729,12 +2729,7 @@ internal void PopulateScenePlacedObjects(Scene sceneToFilterBy, bool clearSceneP
{
ScenePlacedObjects.Clear();
}

#if UNITY_2023_1_OR_NEWER
var networkObjects = UnityEngine.Object.FindObjectsByType<NetworkObject>(FindObjectsSortMode.InstanceID);
#else
var networkObjects = UnityEngine.Object.FindObjectsOfType<NetworkObject>();
#endif
var networkObjects = FindObjects.ByType<NetworkObject>();

// Just add every NetworkObject found that isn't already in the list
// With additive scenes, we can have multiple in-scene placed NetworkObjects with the same GlobalObjectIdHash value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -368,12 +368,7 @@ internal void AddDespawnedInSceneNetworkObjects()
{
m_DespawnedInSceneObjectsSync.Clear();
// Find all active and non-active in-scene placed NetworkObjects
#if UNITY_2023_1_OR_NEWER
var inSceneNetworkObjects = UnityEngine.Object.FindObjectsByType<NetworkObject>(UnityEngine.FindObjectsInactive.Include, UnityEngine.FindObjectsSortMode.InstanceID).Where((c) => c.NetworkManager == m_NetworkManager);
#else
var inSceneNetworkObjects = UnityEngine.Object.FindObjectsOfType<NetworkObject>(includeInactive: true).Where((c) => c.NetworkManager == m_NetworkManager);

#endif
var inSceneNetworkObjects = FindObjects.ByType<NetworkObject>(true, true).Where((c) => c.NetworkManager == m_NetworkManager);
foreach (var sobj in inSceneNetworkObjects)
{
if (sobj.IsSceneObject.HasValue && sobj.IsSceneObject.Value && !sobj.IsSpawned)
Expand Down Expand Up @@ -917,11 +912,7 @@ internal void ReadClientReSynchronizationData(FastBufferReader reader)

if (networkObjectsToRemove.Length > 0)
{
#if UNITY_2023_1_OR_NEWER
var networkObjects = UnityEngine.Object.FindObjectsByType<NetworkObject>(UnityEngine.FindObjectsSortMode.InstanceID);
#else
var networkObjects = UnityEngine.Object.FindObjectsOfType<NetworkObject>();
#endif
var networkObjects = FindObjects.ByType<NetworkObject>(orderByIdentifier: true);
var networkObjectIdToNetworkObject = new Dictionary<ulong, NetworkObject>();
foreach (var networkObject in networkObjects)
{
Expand Down Expand Up @@ -1049,14 +1040,8 @@ private void DeserializeDespawnedInScenePlacedNetworkObjects()
var objectRelativeScene = m_NetworkManager.SceneManager.ScenesLoaded[localSceneHandle];

// Find all active and non-active in-scene placed NetworkObjects
#if UNITY_2023_1_OR_NEWER
var inSceneNetworkObjects = UnityEngine.Object.FindObjectsByType<NetworkObject>(UnityEngine.FindObjectsInactive.Include, UnityEngine.FindObjectsSortMode.InstanceID).Where((c) =>
c.GetSceneOriginHandle() == localSceneHandle && (c.IsSceneObject != false)).ToList();
#else
var inSceneNetworkObjects = UnityEngine.Object.FindObjectsOfType<NetworkObject>(includeInactive: true).Where((c) =>
var inSceneNetworkObjects = FindObjects.ByType<NetworkObject>(true, true).Where((c) =>
c.GetSceneOriginHandle() == localSceneHandle && (c.IsSceneObject != false)).ToList();
#endif


foreach (var inSceneObject in inSceneNetworkObjects)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1369,11 +1369,7 @@ internal void DespawnObject(NetworkObject networkObject, bool destroyObject = fa
// Makes scene objects ready to be reused
internal void ServerResetShudownStateForSceneObjects()
{
#if UNITY_2023_1_OR_NEWER
var networkObjects = UnityEngine.Object.FindObjectsByType<NetworkObject>(FindObjectsSortMode.InstanceID).Where((c) => c.IsSceneObject != null && c.IsSceneObject == true);
#else
var networkObjects = UnityEngine.Object.FindObjectsOfType<NetworkObject>().Where((c) => c.IsSceneObject != null && c.IsSceneObject == true);
#endif
var networkObjects = FindObjects.ByType<NetworkObject>(orderByIdentifier: true).Where((c) => c.IsSceneObject != null && c.IsSceneObject == true);
foreach (var sobj in networkObjects)
{
sobj.IsSpawned = false;
Expand Down Expand Up @@ -1404,11 +1400,7 @@ internal void ServerDestroySpawnedSceneObjects()

internal void DespawnAndDestroyNetworkObjects()
{
#if UNITY_2023_1_OR_NEWER
var networkObjects = UnityEngine.Object.FindObjectsByType<NetworkObject>(FindObjectsSortMode.InstanceID);
#else
var networkObjects = UnityEngine.Object.FindObjectsOfType<NetworkObject>();
#endif
var networkObjects = FindObjects.ByType<NetworkObject>(orderByIdentifier: true);

foreach (var networkObject in networkObjects)
{
Expand Down Expand Up @@ -1463,11 +1455,7 @@ internal void DespawnAndDestroyNetworkObjects()

internal void DestroySceneObjects()
{
#if UNITY_2023_1_OR_NEWER
var networkObjects = UnityEngine.Object.FindObjectsByType<NetworkObject>(FindObjectsSortMode.InstanceID);
#else
var networkObjects = UnityEngine.Object.FindObjectsOfType<NetworkObject>();
#endif
var networkObjects = FindObjects.ByType<NetworkObject>(orderByIdentifier: true);

for (int i = 0; i < networkObjects.Length; i++)
{
Expand Down Expand Up @@ -1498,11 +1486,7 @@ internal void DestroySceneObjects()

internal void ServerSpawnSceneObjectsOnStartSweep()
{
#if UNITY_2023_1_OR_NEWER
var networkObjects = UnityEngine.Object.FindObjectsByType<NetworkObject>(FindObjectsSortMode.InstanceID);
#else
var networkObjects = UnityEngine.Object.FindObjectsOfType<NetworkObject>();
#endif
var networkObjects = FindObjects.ByType<NetworkObject>(orderByIdentifier: true);
var networkObjectsToSpawn = new List<NetworkObject>();
for (int i = 0; i < networkObjects.Length; i++)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,16 @@
"name": "Unity",
"expression": "6000.5.0a1",
"define": "SCENE_MANAGEMENT_SCENE_HANDLE_MUST_USE_ULONG"
},
{
"name": "Unity",
"expression": "[6000.4.0b5,6000.5.0a1)",
"define": "NGO_FINDOBJECTS_NOSORTING"
},
{
"name": "Unity",
"expression": "6000.5.0a8",
"define": "NGO_FINDOBJECTS_NOSORTING"
Comment on lines +90 to +99
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see you implemented this retro-compatibility fix to avoid compilation errors on alpha/beta versions that didn't have the deprecation change yet, but do we intend to support those versions in the long run?

The risk I foresee is that we fill our code with a bunch of defines for "almost-dead code", with an increased maintenance burden for us, and higher rissk to introduce bugs as we have to support multiple workflows.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making it work with earlier versions actually prevents users that have yet to upgrade their editor from breaking if they decide to upgrade to the current version of NGO (whichever version that will be once this PR is merged). Otherwise, it would be considered a breaking change for earlier 6000.4 & 6000.5 versions.

But yeah... that is a good point and one of the reasons why I migrated all of the changes into the single FindObjects.ByType<T> method... so there is one place that handles this which also reduces the number of times we have to use the conditional define.

Test project had two places that I added this to in order to prevent from having to make FindObjects public.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also do the work to remove the scripting defines once we no longer support that Unity version. So these defines won't live forever

}
],
"noEngineReferences": false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,12 +278,7 @@ private void SpawnClients(bool clearTestDeferredMessageManagerCallFlags = true)

private T GetComponentForClient<T>(ulong clientId) where T : NetworkBehaviour
{
#if UNITY_2023_1_OR_NEWER
var componentsToFind = Object.FindObjectsByType<T>(FindObjectsSortMode.InstanceID);
#else
var componentsToFind = Object.FindObjectsOfType<T>();
#endif

var componentsToFind = FindObjects.ByType<T>();
foreach (var component in componentsToFind)
{
if (component.IsSpawned && component.NetworkManager.LocalClientId == clientId)
Expand Down Expand Up @@ -761,11 +756,7 @@ bool HaveAllClientsSpawned()
{
var found1 = false;
var found2 = false;
#if UNITY_2023_1_OR_NEWER
var deferredMessageTestRpcComponents = Object.FindObjectsByType<DeferredMessageTestRpcComponent>(FindObjectsSortMode.None);
#else
var deferredMessageTestRpcComponents = Object.FindObjectsOfType<DeferredMessageTestRpcComponent>();
#endif
var deferredMessageTestRpcComponents = FindObjects.ByType<DeferredMessageTestRpcComponent>();

foreach (var component in deferredMessageTestRpcComponents)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,7 @@ public IEnumerator MyFirstIntegationTest()
{
// Check the condition for this test and automatically handle varying processing
// environments and conditions
#if UNITY_2023_1_OR_NEWER
yield return WaitForConditionOrTimeOut(() =>
Object.FindObjectsByType<NetworkVisibilityComponent>(FindObjectsSortMode.None).Where(
(c) => c.IsSpawned).Count() == 2);
#else
yield return WaitForConditionOrTimeOut(() =>
Object.FindObjectsOfType<NetworkVisibilityComponent>().Where(
(c) => c.IsSpawned).Count() == 2);
#endif
yield return WaitForConditionOrTimeOut(() => FindObjects.ByType<NetworkVisibilityComponent>().Where((c) => c.IsSpawned).Count() == 2);
Assert.False(s_GlobalTimeoutHelper.TimedOut, "Timed out waiting for instances " +
"to be detected!");
}
Expand Down Expand Up @@ -69,16 +61,7 @@ public IEnumerator MyFirstIntegationTest()
{
// Check the condition for this test and automatically handle varying processing
// environments and conditions
#if UNITY_2023_1_OR_NEWER
yield return WaitForConditionOrTimeOut(() =>
Object.FindObjectsByType<NetworkVisibilityComponent>(FindObjectsSortMode.None).Where(
(c) => c.IsSpawned).Count() == 2);
#else
yield return WaitForConditionOrTimeOut(() =>
Object.FindObjectsOfType<NetworkVisibilityComponent>().Where(
(c) => c.IsSpawned).Count() == 2);
#endif

yield return WaitForConditionOrTimeOut(() => FindObjects.ByType<NetworkVisibilityComponent>().Where((c) => c.IsSpawned).Count() == 2);
Assert.False(s_GlobalTimeoutHelper.TimedOut, "Timed out waiting for instances " +
"to be detected!");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,7 @@ public IEnumerator WhenOwnershipIsChanged_OwnershipValuesUpdateCorrectly()
Assert.IsFalse(serverBehaviour.IsOwnedByServer);
Assert.AreEqual(m_ClientNetworkManagers[0].LocalClientId, serverBehaviour.OwnerClientId);

#if UNITY_2023_1_OR_NEWER
var clientObject = Object.FindObjectsByType<NetworkObject>(FindObjectsSortMode.InstanceID).Where((obj) => obj.NetworkManagerOwner == m_ClientNetworkManagers[0]).FirstOrDefault();
#else
var clientObject = Object.FindObjectsOfType<NetworkObject>().Where((obj) => obj.NetworkManagerOwner == m_ClientNetworkManagers[0]).FirstOrDefault();
#endif

var clientObject = FindObjects.ByType<NetworkObject>(orderByIdentifier: true).Where((obj) => obj.NetworkManagerOwner == m_ClientNetworkManagers[0]).FirstOrDefault();

Assert.IsNotNull(clientObject);
Assert.IsTrue(clientObject.IsOwner);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using Unity.Netcode.TestHelpers.Runtime;
using UnityEngine;
using UnityEngine.TestTools.Utils;
using Object = UnityEngine.Object;

namespace Unity.Netcode.RuntimeTests
{
Expand Down Expand Up @@ -90,7 +89,8 @@ public AnticipatedNetworkTransform GetTestComponent()

public AnticipatedNetworkTransform GetServerComponent()
{
foreach (var obj in Object.FindObjectsByType<AnticipatedNetworkTransform>(FindObjectsSortMode.None))
var anticipatedNetworkTransforms = FindObjects.ByType<AnticipatedNetworkTransform>();
foreach (var obj in anticipatedNetworkTransforms)
{
if (obj.NetworkManager == m_ServerNetworkManager && obj.OwnerClientId == m_ClientNetworkManagers[0].LocalClientId)
{
Expand All @@ -103,7 +103,8 @@ public AnticipatedNetworkTransform GetServerComponent()

public AnticipatedNetworkTransform GetOtherClientComponent()
{
foreach (var obj in Object.FindObjectsByType<AnticipatedNetworkTransform>(FindObjectsSortMode.None))
var anticipatedNetworkTransforms = FindObjects.ByType<AnticipatedNetworkTransform>();
foreach (var obj in anticipatedNetworkTransforms)
{
if (obj.NetworkManager == m_ClientNetworkManagers[1] && obj.OwnerClientId == m_ClientNetworkManagers[0].LocalClientId)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using NUnit.Framework;
using Unity.Netcode.TestHelpers.Runtime;
using UnityEngine;
using Object = UnityEngine.Object;

namespace Unity.Netcode.RuntimeTests
{
Expand Down Expand Up @@ -79,7 +78,8 @@ public NetworkVariableAnticipationComponent GetTestComponent()

public NetworkVariableAnticipationComponent GetServerComponent()
{
foreach (var obj in Object.FindObjectsByType<NetworkVariableAnticipationComponent>(FindObjectsSortMode.None))
var objects = FindObjects.ByType<NetworkVariableAnticipationComponent>();
foreach (var obj in objects)
{
if (obj.NetworkManager == m_ServerNetworkManager && obj.OwnerClientId == m_ClientNetworkManagers[0].LocalClientId)
{
Expand All @@ -92,7 +92,8 @@ public NetworkVariableAnticipationComponent GetServerComponent()

public NetworkVariableAnticipationComponent GetOtherClientComponent()
{
foreach (var obj in Object.FindObjectsByType<NetworkVariableAnticipationComponent>(FindObjectsSortMode.None))
var objects = FindObjects.ByType<NetworkVariableAnticipationComponent>();
foreach (var obj in objects)
{
if (obj.NetworkManager == m_ClientNetworkManagers[1] && obj.OwnerClientId == m_ClientNetworkManagers[0].LocalClientId)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public IEnumerator WhenNewValueIsLessThanThresholdButMaxTimeHasPassed_VariableIs
authorityComponent.TheVariable.Value = newValue;
// We expect a timeout for this condition
yield return WaitForConditionOrTimeOut(() => AllAuthorityInstanceValuesMatch(newValue), timeoutHelper);
Assert.True(timeoutHelper.TimedOut, $"Non-authority instances recieved changes when they should not have!");
Assert.True(timeoutHelper.TimedOut, $"Non-authority instances recieved changes when they should not have!\n {m_ErrorLog.ToString()}");

// Now we expect this to not timeout
yield return WaitForConditionOrTimeOut(() => AllAuthorityInstanceValuesMatch(newValue), timeoutHelper);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,21 +49,21 @@ protected override IEnumerator OnServerAndClientsConnected()
[UnityTest]
public IEnumerator HiddenObjectsTest()
{
yield return WaitForConditionOrTimeOut(() => Object.FindObjectsByType<NetworkVisibilityComponent>(FindObjectsSortMode.None).Where((c) => c.IsSpawned).Count() == TotalClients);
AssertOnTimeout($"Timed out waiting for the visible object count to equal {TotalClients}!Actual count {Object.FindObjectsByType<NetworkVisibilityComponent>(FindObjectsSortMode.None).Count(c => c.IsSpawned)}");
yield return WaitForConditionOrTimeOut(() => FindObjects.ByType<NetworkVisibilityComponent>().Where((c) => c.IsSpawned).Count() == TotalClients);
AssertOnTimeout($"Timed out waiting for the visible object count to equal {TotalClients}!Actual count {FindObjects.ByType<NetworkVisibilityComponent>().Count(c => c.IsSpawned)}");
}

[UnityTest]
public IEnumerator HideShowAndDeleteTest()
{
yield return WaitForConditionOrTimeOut(() => Object.FindObjectsByType<NetworkVisibilityComponent>(FindObjectsSortMode.None).Count(c => c.IsSpawned) == TotalClients);
yield return WaitForConditionOrTimeOut(() => FindObjects.ByType<NetworkVisibilityComponent>().Count(c => c.IsSpawned) == TotalClients);

AssertOnTimeout($"Timed out waiting for the visible object count to equal {TotalClients}! Actual count {Object.FindObjectsByType<NetworkVisibilityComponent>(FindObjectsSortMode.None).Count(c => c.IsSpawned)}");
AssertOnTimeout($"Timed out waiting for the visible object count to equal {TotalClients}! Actual count {FindObjects.ByType<NetworkVisibilityComponent>().Count(c => c.IsSpawned)}");

var sessionOwnerNetworkObject = m_SpawnedObject.GetComponent<NetworkObject>();
var nonAuthority = GetNonAuthorityNetworkManager();
sessionOwnerNetworkObject.NetworkHide(nonAuthority.LocalClientId);
yield return WaitForConditionOrTimeOut(() => Object.FindObjectsByType<NetworkVisibilityComponent>(FindObjectsSortMode.None).Where((c) => c.IsSpawned).Count() == TotalClients - 1);
yield return WaitForConditionOrTimeOut(() => FindObjects.ByType<NetworkVisibilityComponent>().Where((c) => c.IsSpawned).Count() == TotalClients - 1);
AssertOnTimeout($"Timed out waiting for {m_SpawnedObject.name} to be hidden from client!");
var networkObjectId = sessionOwnerNetworkObject.NetworkObjectId;
sessionOwnerNetworkObject.NetworkShow(nonAuthority.LocalClientId);
Expand Down
Loading