Skip to content

Commit 00faa47

Browse files
committed
chore: Replace IsSceneObject with InScenePlaced bool
1 parent 5d6a3c7 commit 00faa47

28 files changed

Lines changed: 256 additions & 182 deletions
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using UnityEditor;
2+
using UnityEditor.Build;
3+
using UnityEditor.Build.Reporting;
4+
using UnityEngine;
5+
using UnityEngine.SceneManagement;
6+
7+
namespace Unity.Netcode.Editor
8+
{
9+
public class InScenePlacedPrefab : IProcessSceneWithReport
10+
{
11+
public int callbackOrder => 0;
12+
public void OnProcessScene(Scene scene, BuildReport report)
13+
{
14+
foreach (var networkObject in FindObjects.FromSceneByType<NetworkObject>(scene, true))
15+
{
16+
networkObject.InScenePlaced = true;
17+
}
18+
}
19+
}
20+
21+
public class InScenePlacedPrefabBuilder : AssetPostprocessor
22+
{
23+
public void OnPostprocessPrefab(GameObject root)
24+
{
25+
var networkObjects = root.GetComponentsInChildren<NetworkObject>(true);
26+
foreach (var networkObject in networkObjects)
27+
{
28+
networkObject.InScenePlaced = false;
29+
}
30+
}
31+
}
32+
}

com.unity.netcode.gameobjects/Editor/InScenePlacedPrefab.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

com.unity.netcode.gameobjects/Editor/NetworkObjectEditor.cs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,10 @@ public override void OnInspectorGUI()
6767
EditorGUILayout.Toggle(nameof(NetworkObject.IsOwner), m_NetworkObject.IsOwner);
6868
EditorGUILayout.Toggle(nameof(NetworkObject.IsOwnedByServer), m_NetworkObject.IsOwnedByServer);
6969
EditorGUILayout.Toggle(nameof(NetworkObject.IsPlayerObject), m_NetworkObject.IsPlayerObject);
70-
if (m_NetworkObject.IsSceneObject.HasValue)
71-
{
72-
EditorGUILayout.Toggle(nameof(NetworkObject.IsSceneObject), m_NetworkObject.IsSceneObject.Value);
73-
}
74-
else
75-
{
76-
EditorGUILayout.TextField(nameof(NetworkObject.IsSceneObject), "null");
77-
}
70+
#pragma warning disable CS0618 // Type or member is obsolete
71+
// TODO-3.x: Update name in 3.x branch
72+
EditorGUILayout.Toggle(nameof(NetworkObject.IsSceneObject), m_NetworkObject.InScenePlaced);
73+
#pragma warning restore CS0618 // Type or member is obsolete
7874
EditorGUILayout.Toggle(nameof(NetworkObject.DestroyWithScene), m_NetworkObject.DestroyWithScene);
7975
EditorGUILayout.TextField(nameof(NetworkObject.NetworkManager), m_NetworkObject.NetworkManager == null ? "null" : m_NetworkObject.NetworkManager.gameObject.name);
8076
GUI.enabled = guiEnabled;

com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2231,7 +2231,7 @@ private bool CheckForStateChange(ref NetworkTransformState networkState, bool is
22312231

22322232
// In-scene placed NetworkObjects parented under a GameObject with no
22332233
// NetworkObject preserve their lossyScale when synchronizing.
2234-
if (parentNetworkObject == null && NetworkObject.IsSceneObject != false)
2234+
if (parentNetworkObject == null && NetworkObject.InScenePlaced)
22352235
{
22362236
hasParentNetworkObject = true;
22372237
}

com.unity.netcode.gameobjects/Runtime/Connection/NetworkConnectionManager.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1184,7 +1184,11 @@ internal void CreateAndSpawnPlayer(ulong ownerId)
11841184
return;
11851185
}
11861186

1187-
networkObject.IsSceneObject = false;
1187+
#pragma warning disable CS0618 // Type or member is obsolete
1188+
// Obsolete with warning means we need the underlying behaviour to keep existing
1189+
// TODO: remove in the 3.x branch
1190+
networkObject.SetSceneObjectStatus(false);
1191+
#pragma warning restore CS0618 // Type or member is obsolete
11881192
networkObject.NetworkManagerOwner = NetworkManager;
11891193
networkObject.SpawnAsPlayerObject(ownerId, networkObject.DestroyWithScene);
11901194
}

com.unity.netcode.gameobjects/Runtime/Core/FindObjects.cs

Lines changed: 93 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
#if NGO_FINDOBJECTS_NOSORTING
22
using System;
33
#endif
4+
using System;
5+
using System.Collections;
6+
using System.Collections.Generic;
47
using System.Runtime.CompilerServices;
8+
using UnityEngine;
9+
using UnityEngine.SceneManagement;
510
using Object = UnityEngine.Object;
611

712
namespace Unity.Netcode
@@ -18,14 +23,14 @@ internal static class FindObjects
1823
/// <summary>
1924
/// Replaces <see cref="Object.FindObjectsByType"/> to have one place where these changes are applied.
2025
/// </summary>
21-
/// <typeparam name="T"></typeparam>
26+
/// <typeparam name="T">The type of object to find. Must be a reference type derived from <see cref="Object"/></typeparam>
2227
/// <param name="includeInactive">When true, inactive objects will be included.</param>
2328
/// <param name="orderByIdentifier">When true, the array returned will be sorted by identifier.</param>
2429
/// <returns>Results as an <see cref="Array"/> of type T</returns>
2530
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2631
public static T[] ByType<T>(bool includeInactive = false, bool orderByIdentifier = false) where T : Object
2732
{
28-
var inactive = includeInactive ? UnityEngine.FindObjectsInactive.Include : UnityEngine.FindObjectsInactive.Exclude;
33+
var inactive = includeInactive ? FindObjectsInactive.Include : FindObjectsInactive.Exclude;
2934
#if NGO_FINDOBJECTS_NOSORTING
3035
var results = Object.FindObjectsByType<T>(inactive);
3136
#if !NGO_FINDOBJECTS_UNORDERED_IDS
@@ -35,9 +40,94 @@ public static T[] ByType<T>(bool includeInactive = false, bool orderByIdentifier
3540
}
3641
#endif
3742
#else
38-
var results = Object.FindObjectsByType<T>(inactive, orderByIdentifier ? UnityEngine.FindObjectsSortMode.InstanceID : UnityEngine.FindObjectsSortMode.None);
43+
var results = Object.FindObjectsByType<T>(inactive, orderByIdentifier ? FindObjectsSortMode.InstanceID : FindObjectsSortMode.None);
3944
#endif
4045
return results;
4146
}
47+
48+
/// <summary>
49+
/// Returns an enumerator that enumerates over all the components of a given type in a scene.
50+
/// </summary>
51+
/// <param name="scene">The scene to use for searching</param>
52+
/// <param name="includeInactive">When true, inactive objects will be included.</param>
53+
/// <typeparam name="T">Type of <see cref="Component"/> to get from the scene</typeparam>
54+
/// <returns>a generator that yields successive NetworkObjects in the current scene</returns>
55+
public static IEnumerable<T> FromSceneByType<T>(Scene scene, bool includeInactive) where T : Component
56+
{
57+
return new ObjectsInSceneEnumerator<T>(scene, includeInactive);
58+
}
59+
60+
/// <summary>
61+
/// An Enumerator that enumerates over each component of type <see cref="T"/> in the given scene.
62+
/// </summary>
63+
/// <typeparam name="T">Type of <see cref="Component"/> to get from the scene</typeparam>
64+
private struct ObjectsInSceneEnumerator<T> : IEnumerable<T>, IEnumerator<T> where T : Component
65+
{
66+
private readonly GameObject[] m_RootObjects;
67+
private int m_RootIndex;
68+
private T[] m_CurrentChildObjects;
69+
private int m_CurrentChildIndex;
70+
71+
private readonly bool m_IncludeInactive;
72+
73+
internal ObjectsInSceneEnumerator(Scene scene, bool includeInactive)
74+
{
75+
m_IncludeInactive = includeInactive;
76+
77+
m_RootObjects = scene.GetRootGameObjects();
78+
m_RootIndex = 0;
79+
m_CurrentChildObjects = null;
80+
m_CurrentChildIndex = 0;
81+
Current = null;
82+
}
83+
84+
public void Dispose() { }
85+
86+
public bool MoveNext()
87+
{
88+
while (m_CurrentChildObjects == null && m_RootIndex < m_RootObjects.Length)
89+
{
90+
m_CurrentChildObjects = m_RootObjects[m_RootIndex].GetComponentsInChildren<T>(m_IncludeInactive);
91+
m_RootIndex++;
92+
93+
if (m_CurrentChildObjects.Length == 0)
94+
{
95+
m_CurrentChildObjects = null;
96+
}
97+
}
98+
99+
if (m_CurrentChildObjects != null && m_CurrentChildIndex < m_CurrentChildObjects.Length)
100+
{
101+
Current = m_CurrentChildObjects[m_CurrentChildIndex];
102+
m_CurrentChildIndex++;
103+
104+
if (m_CurrentChildIndex >= m_CurrentChildObjects.Length)
105+
{
106+
m_CurrentChildIndex = 0;
107+
m_CurrentChildObjects = null;
108+
}
109+
return true;
110+
}
111+
112+
Current = null;
113+
return false;
114+
}
115+
116+
public void Reset()
117+
{
118+
m_RootIndex = 0;
119+
m_CurrentChildObjects = null;
120+
m_CurrentChildIndex = 0;
121+
Current = null;
122+
}
123+
124+
object IEnumerator.Current => Current;
125+
126+
public T Current { get; private set; }
127+
128+
public IEnumerator<T> GetEnumerator() => this;
129+
130+
IEnumerator IEnumerable.GetEnumerator() => this;
131+
}
42132
}
43133
}

com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1641,7 +1641,7 @@ internal void ShutdownInternal()
16411641
// place (i.e. sending any last state updates or the like).
16421642

16431643
SpawnManager?.DespawnAndDestroyNetworkObjects();
1644-
SpawnManager?.ServerResetShudownStateForSceneObjects();
1644+
SpawnManager?.ServerResetShutdownStateForSceneObjects();
16451645
////
16461646

16471647
RpcTarget?.Dispose();

com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ internal void OnValidate()
291291
if (GlobalObjectIdHash != oldValue)
292292
{
293293
// Check if this is an in-scnee placed NetworkObject (Special Case for In-Scene Placed).
294-
if (IsSceneObject.HasValue && IsSceneObject.Value)
294+
if (InScenePlaced)
295295
{
296296
// Sanity check to make sure this is a scene placed object.
297297
if (globalId.identifierType != k_SceneObjectType)
@@ -340,7 +340,12 @@ private void CheckForInScenePlaced()
340340
EditorUtility.SetDirty(this);
341341
}
342342
}
343-
IsSceneObject = true;
343+
344+
#pragma warning disable CS0618 // Type or member is obsolete
345+
// Obsolete with warning means we need the underlying behaviour to keep existing
346+
// TODO-3.x: remove in the 3.x branch
347+
SetSceneObjectStatus(true);
348+
#pragma warning restore CS0618 // Type or member is obsolete
344349

345350
// Default scene migration synchronization to false for in-scene placed NetworkObjects
346351
SceneMigrationSynchronization = false;
@@ -1225,15 +1230,21 @@ private bool InternalHasAuthority()
12251230
public bool IsSpawned { get; internal set; }
12261231

12271232
/// <summary>
1228-
/// Gets if the object is a SceneObject, null if it's not yet spawned but is a scene object.
1233+
/// Gets if the object is a SceneObject.
12291234
/// </summary>
1235+
[Obsolete("Use InScenePlaced instead")]
12301236
public bool? IsSceneObject { get; internal set; }
12311237

1232-
//DANGOEXP TODO: Determine if we want to keep this
1238+
[field: HideInInspector]
1239+
[field: SerializeField]
1240+
public bool InScenePlaced { get; internal set; }
1241+
12331242
/// <summary>
12341243
/// Sets whether this NetworkObject was instantiated as part of a scene
12351244
/// </summary>
1245+
/// <remarks>Only use this when using custom scene loading</remarks>
12361246
/// <param name="isSceneObject">When true, marks this as a scene-instantiated object; when false, marks it as runtime-instantiated</param>
1247+
[Obsolete("SetSceneObjectStatus is now calculated during the build.")]
12371248
public void SetSceneObjectStatus(bool isSceneObject = false)
12381249
{
12391250
IsSceneObject = isSceneObject;
@@ -1457,7 +1468,7 @@ internal Scene SceneOrigin
14571468
/// </summary>
14581469
internal NetworkSceneHandle GetSceneOriginHandle()
14591470
{
1460-
if (SceneOriginHandle.IsEmpty() && IsSpawned && IsSceneObject != false)
1471+
if (SceneOriginHandle.IsEmpty() && IsSpawned && InScenePlaced)
14611472
{
14621473
if (NetworkManager.LogLevel <= LogLevel.Error)
14631474
{
@@ -1622,7 +1633,7 @@ public void NetworkHide(ulong clientId)
16221633
var message = new DestroyObjectMessage
16231634
{
16241635
NetworkObjectId = NetworkObjectId,
1625-
DestroyGameObject = !IsSceneObject.Value,
1636+
DestroyGameObject = !InScenePlaced,
16261637
IsDistributedAuthority = NetworkManagerOwner.DistributedAuthorityMode,
16271638
IsTargetedDestroy = NetworkManagerOwner.DistributedAuthorityMode,
16281639
TargetClientId = clientId, // Just always populate this value whether we write it or not
@@ -1750,7 +1761,7 @@ private void OnDestroy()
17501761
var isStillValid = gameObject != null && gameObject.scene.IsValid() && gameObject.scene.isLoaded;
17511762

17521763
// If we're not the authority and everything is valid and dynamically spawned, then the destroy is not valid.
1753-
if (!isAuthorityDestroy && IsSceneObject == false && isStillValid)
1764+
if (!isAuthorityDestroy && !InScenePlaced && isStillValid)
17541765
{
17551766
if (networkManager.LogLevel <= LogLevel.Error)
17561767
{
@@ -1849,7 +1860,7 @@ internal void SpawnInternal(bool destroyWithScene, ulong ownerClientId, bool pla
18491860
}
18501861
}
18511862

1852-
if (!NetworkManagerOwner.SpawnManager.AuthorityLocalSpawn(this, NetworkManagerOwner.SpawnManager.GetNetworkObjectId(), IsSceneObject.HasValue && IsSceneObject.Value, playerObject, ownerClientId, destroyWithScene))
1863+
if (!NetworkManagerOwner.SpawnManager.AuthorityLocalSpawn(this, NetworkManagerOwner.SpawnManager.GetNetworkObjectId(), InScenePlaced, playerObject, ownerClientId, destroyWithScene))
18531864
{
18541865
if (NetworkManagerOwner.LogLevel <= LogLevel.Normal)
18551866
{
@@ -2528,8 +2539,7 @@ internal bool ApplyNetworkParenting(bool removeParent = false, bool ignoreNotSpa
25282539
// Handle the first in-scene placed NetworkObject parenting scenarios. Once the m_LatestParent
25292540
// has been set, this will not be entered into again (i.e. the later code will be invoked and
25302541
// users will get notifications when the parent changes).
2531-
var isInScenePlaced = IsSceneObject.HasValue && IsSceneObject.Value;
2532-
if (transform.parent != null && !removeParent && !m_LatestParent.HasValue && isInScenePlaced)
2542+
if (transform.parent != null && !removeParent && !m_LatestParent.HasValue && InScenePlaced)
25332543
{
25342544
var parentNetworkObject = transform.parent.GetComponent<NetworkObject>();
25352545

@@ -3271,7 +3281,7 @@ internal SerializedObject Serialize(ulong targetClientId = NetworkManager.Server
32713281
NetworkObjectId = NetworkObjectId,
32723282
OwnerClientId = OwnerClientId,
32733283
IsPlayerObject = IsPlayerObject,
3274-
IsSceneObject = IsSceneObject ?? true,
3284+
IsSceneObject = InScenePlaced,
32753285
DestroyWithScene = DestroyWithScene,
32763286
DontDestroyWithOwner = DontDestroyWithOwner,
32773287
HasOwnershipFlags = NetworkManagerOwner.DistributedAuthorityMode,
@@ -3456,7 +3466,7 @@ internal void SubscribeToActiveSceneForSynch()
34563466
{
34573467
if (ActiveSceneSynchronization)
34583468
{
3459-
if (IsSceneObject.HasValue && !IsSceneObject.Value)
3469+
if (!InScenePlaced)
34603470
{
34613471
// Just in case it is a recycled NetworkObject, unsubscribe first
34623472
SceneManager.activeSceneChanged -= CurrentlyActiveSceneChanged;
@@ -3473,7 +3483,7 @@ private void CurrentlyActiveSceneChanged(Scene current, Scene next)
34733483
{
34743484
// Early exit if the NetworkObject is not spawned, is an in-scene placed NetworkObject,
34753485
// or the NetworkManager is shutting down.
3476-
if (!IsSpawned || IsSceneObject != false || NetworkManagerOwner.ShutdownInProgress)
3486+
if (!IsSpawned || NetworkManagerOwner.ShutdownInProgress || InScenePlaced)
34773487
{
34783488
return;
34793489
}
@@ -3483,7 +3493,7 @@ private void CurrentlyActiveSceneChanged(Scene current, Scene next)
34833493
{
34843494
// Only dynamically spawned NetworkObjects that are not already in the newly assigned active scene will migrate
34853495
// and update their scene handles
3486-
if (IsSceneObject.HasValue && !IsSceneObject.Value && gameObject.scene != next && gameObject.transform.parent == null)
3496+
if (gameObject.scene != next && gameObject.transform.parent == null)
34873497
{
34883498
SceneManager.MoveGameObjectToScene(gameObject, next);
34893499
SceneChangedUpdate(next);
@@ -3571,7 +3581,7 @@ internal bool UpdateForSceneChanges()
35713581
// the NetworkManager is shutting down, the NetworkObject is not spawned, it is an in-scene placed
35723582
// NetworkObject, or the GameObject's current scene handle is the same as the SceneOriginHandle
35733583
if (!SceneMigrationSynchronization || !IsSpawned || NetworkManagerOwner.ShutdownInProgress ||
3574-
!NetworkManagerOwner.NetworkConfig.EnableSceneManagement || IsSceneObject != false || !gameObject)
3584+
!NetworkManagerOwner.NetworkConfig.EnableSceneManagement || InScenePlaced || !gameObject)
35753585
{
35763586
// Stop checking for a scene migration
35773587
return false;
@@ -3606,15 +3616,15 @@ internal uint CheckForGlobalObjectIdHashOverride()
36063616

36073617
// If scene management is disabled and this is an in-scene placed NetworkObject then go ahead
36083618
// and send the InScenePlacedSourcePrefab's GlobalObjectIdHash value (i.e. what to dynamically spawn)
3609-
if (!networkManager.NetworkConfig.EnableSceneManagement && IsSceneObject.Value && InScenePlacedSourceGlobalObjectIdHash != 0)
3619+
if (!networkManager.NetworkConfig.EnableSceneManagement && InScenePlaced && InScenePlacedSourceGlobalObjectIdHash != 0)
36103620
{
36113621
return InScenePlacedSourceGlobalObjectIdHash;
36123622
}
36133623

36143624
// If the PrefabGlobalObjectIdHash is a non-zero value and the GlobalObjectIdHash value is
36153625
// different from the PrefabGlobalObjectIdHash value, then the NetworkObject instance is
36163626
// an override for the original network prefab (i.e. PrefabGlobalObjectIdHash)
3617-
if (!IsSceneObject.Value && GlobalObjectIdHash != PrefabGlobalObjectIdHash)
3627+
if (!InScenePlaced && GlobalObjectIdHash != PrefabGlobalObjectIdHash)
36183628
{
36193629
// If the PrefabGlobalObjectIdHash is already populated (i.e. InstantiateAndSpawn used), then return this
36203630
if (PrefabGlobalObjectIdHash != 0)

com.unity.netcode.gameobjects/Runtime/SceneManagement/DefaultSceneManagerHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ public void MoveObjectsFromSceneToDontDestroyOnLoad(ref NetworkManager networkMa
311311
if (!networkObject.DestroyWithScene && networkObject.gameObject.scene != networkManager.SceneManager.DontDestroyOnLoadScene)
312312
{
313313
// Only move dynamically spawned NetworkObjects with no parent as the children will follow
314-
if (networkObject.gameObject.transform.parent == null && networkObject.IsSceneObject != null && !networkObject.IsSceneObject.Value)
314+
if (networkObject.gameObject.transform.parent == null && !networkObject.InScenePlaced)
315315
{
316316
UnityEngine.Object.DontDestroyOnLoad(networkObject.gameObject);
317317
}

0 commit comments

Comments
 (0)