Utils.IsSceneObject common function for NetworkServer/Client

This commit is contained in:
vis2k 2022-09-17 17:02:06 +08:00
parent a99bc0ebf5
commit a94fe67c23
4 changed files with 27 additions and 40 deletions

View File

@ -1144,21 +1144,6 @@ static NetworkIdentity GetAndRemoveSceneObject(ulong sceneId)
return null; return null;
} }
// Checks if identity is not spawned yet, not hidden and has sceneId
// TODO merge with ValidateSceneObject on server
static bool IsSceneObject(NetworkIdentity identity)
{
// not spawned yet, not hidden, etc.?
// need to ensure it's not active yet because
// PrepareToSpawnSceneObjects may be called multiple times in case
// the ObjectSpawnStarted message is received multiple times.
return !identity.gameObject.activeSelf &&
identity.gameObject.hideFlags != HideFlags.NotEditable &&
identity.gameObject.hideFlags != HideFlags.HideAndDontSave &&
identity.sceneId != 0;
}
/// <summary>Call this after loading/unloading a scene in the client after connection to register the spawnable objects</summary> /// <summary>Call this after loading/unloading a scene in the client after connection to register the spawnable objects</summary>
public static void PrepareToSpawnSceneObjects() public static void PrepareToSpawnSceneObjects()
{ {
@ -1170,7 +1155,11 @@ public static void PrepareToSpawnSceneObjects()
foreach (NetworkIdentity identity in allIdentities) foreach (NetworkIdentity identity in allIdentities)
{ {
// add all unspawned NetworkIdentities to spawnable objects // add all unspawned NetworkIdentities to spawnable objects
if (IsSceneObject(identity)) // need to ensure it's not active yet because
// PrepareToSpawnSceneObjects may be called multiple times in case
// the ObjectSpawnStarted message is received multiple times.
if (Utils.IsSceneObject(identity) &&
!identity.gameObject.activeSelf)
{ {
if (spawnableObjects.TryGetValue(identity.sceneId, out NetworkIdentity existingIdentity)) if (spawnableObjects.TryGetValue(identity.sceneId, out NetworkIdentity existingIdentity))
{ {

View File

@ -1140,24 +1140,6 @@ public static void Spawn(GameObject obj, Guid assetId, NetworkConnection ownerCo
SpawnObject(obj, ownerConnection); SpawnObject(obj, ownerConnection);
} }
// TODO merge with ConsiderForSpawning on client
internal static bool IsSceneObject(NetworkIdentity identity)
{
if (identity.gameObject.hideFlags == HideFlags.NotEditable ||
identity.gameObject.hideFlags == HideFlags.HideAndDontSave)
return false;
#if UNITY_EDITOR
// this never seems to trigger.
// even if a prefab is dragged into the scene.
if (UnityEditor.EditorUtility.IsPersistent(identity.gameObject))
return false;
#endif
// If not a scene object
return identity.sceneId != 0;
}
/// <summary>Spawns NetworkIdentities in the scene on the server.</summary> /// <summary>Spawns NetworkIdentities in the scene on the server.</summary>
// NetworkIdentity objects in a scene are disabled by default. Calling // NetworkIdentity objects in a scene are disabled by default. Calling
// SpawnObjects() causes these scene objects to be enabled and spawned. // SpawnObjects() causes these scene objects to be enabled and spawned.
@ -1173,7 +1155,7 @@ public static bool SpawnObjects()
// first pass: activate all scene objects // first pass: activate all scene objects
foreach (NetworkIdentity identity in identities) foreach (NetworkIdentity identity in identities)
{ {
if (IsSceneObject(identity)) if (Utils.IsSceneObject(identity))
{ {
// Debug.Log($"SpawnObjects sceneId:{identity.sceneId:X} name:{identity.gameObject.name}"); // Debug.Log($"SpawnObjects sceneId:{identity.sceneId:X} name:{identity.gameObject.name}");
identity.gameObject.SetActive(true); identity.gameObject.SetActive(true);
@ -1193,7 +1175,7 @@ public static bool SpawnObjects()
// second pass: spawn all scene objects // second pass: spawn all scene objects
foreach (NetworkIdentity identity in identities) foreach (NetworkIdentity identity in identities)
{ {
if (IsSceneObject(identity)) if (Utils.IsSceneObject(identity))
// pass connection so that authority is not lost when server loads a scene // pass connection so that authority is not lost when server loads a scene
// https://github.com/vis2k/Mirror/pull/2987 // https://github.com/vis2k/Mirror/pull/2987
Spawn(identity.gameObject, identity.connectionToClient); Spawn(identity.gameObject, identity.connectionToClient);

View File

@ -51,6 +51,22 @@ public static bool IsPrefab(GameObject obj)
#endif #endif
} }
// simplified IsSceneObject check from Mirror II
public static bool IsSceneObject(NetworkIdentity identity)
{
// original UNET / Mirror still had the IsPersistent check.
// it never fires though. even for Prefabs dragged to the Scene.
// (see Scene Objects example scene.)
// #if UNITY_EDITOR
// if (UnityEditor.EditorUtility.IsPersistent(identity.gameObject))
// return false;
// #endif
return identity.gameObject.hideFlags != HideFlags.NotEditable &&
identity.gameObject.hideFlags != HideFlags.HideAndDontSave &&
identity.sceneId != 0;
}
public static bool IsSceneObjectWithPrefabParent(GameObject gameObject, out GameObject prefab) public static bool IsSceneObjectWithPrefabParent(GameObject gameObject, out GameObject prefab)
{ {
prefab = null; prefab = null;

View File

@ -1032,18 +1032,18 @@ public void IsSceneObject()
identity.sceneId = 42; identity.sceneId = 42;
// should be valid as long as it has a sceneId // should be valid as long as it has a sceneId
Assert.That(NetworkServer.IsSceneObject(identity), Is.True); Assert.That(Utils.IsSceneObject(identity), Is.True);
// shouldn't be valid with 0 sceneID // shouldn't be valid with 0 sceneID
identity.sceneId = 0; identity.sceneId = 0;
Assert.That(NetworkServer.IsSceneObject(identity), Is.False); Assert.That(Utils.IsSceneObject(identity), Is.False);
identity.sceneId = 42; identity.sceneId = 42;
// shouldn't be valid for certain hide flags // shouldn't be valid for certain hide flags
go.hideFlags = HideFlags.NotEditable; go.hideFlags = HideFlags.NotEditable;
Assert.That(NetworkServer.IsSceneObject(identity), Is.False); Assert.That(Utils.IsSceneObject(identity), Is.False);
go.hideFlags = HideFlags.HideAndDontSave; go.hideFlags = HideFlags.HideAndDontSave;
Assert.That(NetworkServer.IsSceneObject(identity), Is.False); Assert.That(Utils.IsSceneObject(identity), Is.False);
} }
[Test] [Test]