mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 02:50:32 +00:00
Additive sceneloading sceneid fix (#175)
* Fix additive scene loading causing duplicate sceneIds by using an offset per scene. * TEST: moved SpawnableObjects to NetworkIdentity. OnDisable adds it to the dict. SpawnObject removes it. * Log if we don't find the spawn scene object * Fix compilation issues * Make PrepareToSpawnSceneObjects public
This commit is contained in:
parent
1785039601
commit
3c0ff33c94
@ -4,6 +4,7 @@
|
||||
using UnityEditor;
|
||||
using UnityEditor.Callbacks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace Mirror
|
||||
{
|
||||
@ -133,6 +134,19 @@ public static void OnPostProcessScene()
|
||||
List<NetworkIdentity> identities = FindObjectsOfType<NetworkIdentity>().ToList();
|
||||
identities.Sort(CompareNetworkIdentitySiblingPaths);
|
||||
|
||||
// sceneId assignments need to work with additive scene loading, so
|
||||
// it can't always start at 1,2,3,4,..., otherwise there will be
|
||||
// sceneId duplicates.
|
||||
// -> we need an offset to start at 1000+1,+2,+3, etc.
|
||||
// -> the most robust way is to split uint value range by sceneCount
|
||||
uint offsetPerScene = uint.MaxValue / (uint)SceneManager.sceneCountInBuildSettings;
|
||||
|
||||
// make sure that there aren't more sceneIds than offsetPerScene
|
||||
if (identities.Count >= offsetPerScene)
|
||||
{
|
||||
Debug.LogWarning(">" + offsetPerScene + " NetworkIdentities in scene. Additive scene loading will cause duplicate ids.");
|
||||
}
|
||||
|
||||
uint nextSceneId = 1;
|
||||
foreach (NetworkIdentity identity in identities)
|
||||
{
|
||||
@ -145,10 +159,15 @@ public static void OnPostProcessScene()
|
||||
if (identity.isClient || identity.isServer)
|
||||
continue;
|
||||
|
||||
identity.gameObject.SetActive(false);
|
||||
identity.ForceSceneId(nextSceneId++);
|
||||
uint offset = (uint)identity.gameObject.scene.buildIndex * offsetPerScene;
|
||||
identity.ForceSceneId(offset + nextSceneId++);
|
||||
if (LogFilter.Debug) { Debug.Log("PostProcess sceneid assigned: name=" + identity.name + " scene=" + identity.gameObject.scene.name + " sceneid=" + identity.sceneId); }
|
||||
|
||||
// disable it AFTER assigning the sceneId.
|
||||
// -> this way NetworkIdentity.OnDisable adds itself to the
|
||||
// spawnableObjects dictionary (only if sceneId != 0)
|
||||
identity.gameObject.SetActive(false);
|
||||
|
||||
// safety check for prefabs with more than one NetworkIdentity
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
GameObject prefabGO = PrefabUtility.GetCorrespondingObjectFromSource(identity.gameObject);
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
@ -180,7 +180,9 @@ internal static bool ConsiderForSpawning(NetworkIdentity identity)
|
||||
identity.sceneId != 0;
|
||||
}
|
||||
|
||||
internal static void PrepareToSpawnSceneObjects()
|
||||
// this needs to be public. If users load/unload a scene in the client after connection
|
||||
// they should call this to register the spawnable objects
|
||||
public static void PrepareToSpawnSceneObjects()
|
||||
{
|
||||
// add all unspawned NetworkIdentities to spawnable objects
|
||||
spawnableObjects = Resources.FindObjectsOfTypeAll<NetworkIdentity>()
|
||||
|
@ -97,6 +97,7 @@ public Guid assetId
|
||||
return string.IsNullOrEmpty(m_AssetId) ? Guid.Empty : new Guid(m_AssetId);
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetDynamicAssetId(Guid newAssetId)
|
||||
{
|
||||
string newAssetIdString = newAssetId.ToString("N");
|
||||
|
Loading…
Reference in New Issue
Block a user