/// <summary>
        /// Whenever another scene is loaded, we have another shot at resolving more cross-scene references
        /// </summary>
        /// <param name="sceneSetup">The AmsMultiSceneSetup that was loaded</param>
        private void HandleNewSceneLoaded(AmsMultiSceneSetup sceneSetup)
        {
            var loadedScene = sceneSetup.gameObject.scene;

            if (!loadedScene.isLoaded)
            {
                Debug.LogErrorFormat(this, "{0} Received HandleNewSceneLoaded from scene {1} which isn't considered loaded.  The scene MUST be considered loaded by this point", GetType().Name, loadedScene.name);
            }

            // Restore any references to this newly loaded scene
            for (int i = 0; i < _crossSceneReferences.Count; ++i)
            {
                var xRef = _crossSceneReferences[i];

                if (!xRef.fromObject)
                {
                    AmsDebug.LogWarning(this, "xRef Index {0} had Null source (probably stale), Consider removing (via right-click on entry)", i);
                    continue;
                }

                if (!_referencesToResolve.Contains(xRef) && xRef.toScene.scene == loadedScene)
                {
                    _referencesToResolve.Add(xRef);
                }
            }

            if (_referencesToResolve.Count > 0)
            {
                AmsDebug.Log(this, "Scene {0} Loaded. {1} Cross-Scene References (in total) from Cross-Scene Manager in {2} are queued for resolve.", loadedScene.name, _referencesToResolve.Count, gameObject.scene.name);
                ConditionalResolveReferences(_referencesToResolve);
            }
        }
        /// <summary>
        /// This is called during the build pipeline to ensure a proper merge from one scene into another, taking into account cross-scene references
        /// </summary>
        /// <param name="sourceSceneSetup">The scene we're merging from</param>
        /// <param name="destSceneSetup">The scene we're merging to</param>
        public static void EditorBuildPipelineMergeScene(AmsMultiSceneSetup sourceSceneSetup, AmsMultiSceneSetup destSceneSetup)
        {
            // This is happening during the build system, so we're going to end up with a scene name of 0.backup
            // So we need to get the actual path from the AmsMultiSceneSetup object and clobber it.
            var amsFromSceneRef = new AmsSceneReference(sourceSceneSetup.gameObject.scene);

            amsFromSceneRef.editorPath = sourceSceneSetup.scenePath;

            var amsIntoSceneRef = new AmsSceneReference(destSceneSetup.gameObject.scene);

            amsIntoSceneRef.editorPath = destSceneSetup.scenePath;

            // Now get the cross-scene references from both scenes to merge them
            var srcCrossSceneRefs = GetSceneSingleton(sourceSceneSetup.gameObject.scene, false);

            if (!srcCrossSceneRefs)
            {
                return;
            }

            var destCrossSceneRefs = GetSceneSingleton(destSceneSetup.gameObject.scene, true);

            for (int i = 0; i < srcCrossSceneRefs._crossSceneReferences.Count; ++i)
            {
                var xRef = srcCrossSceneRefs._crossSceneReferences[i];
                if (!srcCrossSceneRefs._referencesToResolve.Contains(xRef))
                {
                    AmsDebug.Log(srcCrossSceneRefs, "Already resolved xRef {0}. No need to merge it.", xRef);
                    continue;
                }

                AmsDebug.Log(destSceneSetup, "Merging {0} into Scene {1}", xRef, amsIntoSceneRef.editorPath);
                xRef.DEPRECATED_fromScene = amsIntoSceneRef;
                destCrossSceneRefs.AddReference(xRef);
            }

            // Mark this as a merged scene in the destination, so when we look-up cross-scene references we're aware.
            destCrossSceneRefs._mergedScenes.Add(amsFromSceneRef);

            // Destroy this object after the merge is complete (we don't want it merged into the scene)
            GameObject.DestroyImmediate(srcCrossSceneRefs.gameObject, false);
        }
Exemple #3
0
        /// <summary>
        /// Whenever another scene is loaded, we have another shot at resolving more cross-scene references
        /// </summary>
        /// <param name="sceneSetup">The AmsMultiSceneSetup that was loaded</param>
        private void HandleNewSceneLoaded(AmsMultiSceneSetup sceneSetup)
        {
            var loadedScene = sceneSetup.gameObject.scene;

            if (!Application.isPlaying)
            {
                // Restore any references to this newly loaded scene
                foreach (var xRef in _crossSceneReferences)
                {
                    if (!_referencesToResolve.Contains(xRef) && xRef.toScene.scene == loadedScene)
                    {
                        _referencesToResolve.Add(xRef);
                    }
                }
            }

            if (_referencesToResolve.Count > 0)
            {
                AmsDebug.Log(this, "Scene {0} Loaded. {1} Cross-Scene References are queued for resolve.", loadedScene.name, _referencesToResolve.Count);
                StartCoroutine(CoWaitForSceneLoadThenResolveReferences(loadedScene));
            }
        }
        /// <summary>
        /// Whenever a scene is destroyed, we will receive this callback.  In the editor, we can remember that we may be about to lose a cross-scene reference.
        /// </summary>
        /// <param name="sceneSetup"></param>
        private void HandleSceneDestroyed(AmsMultiSceneSetup sceneSetup)
        {
            var destroyedScene = sceneSetup.gameObject.scene;

            if (!destroyedScene.IsValid())
            {
                return;
            }

            // If our own scene is being destroyed, we don't need to do anymore work
            if (destroyedScene == gameObject.scene)
            {
                return;
            }

            // Remove all of the pending refs for that scene.
            _referencesToResolve.RemoveAll(x => x.toScene.scene == destroyedScene);

            // Now we re-add all of the relevant refs to pending.  They'll be re-resolved when the scene is loaded again.
            var allRelevantRefs = _crossSceneReferences.Where(x => x.toScene.scene == destroyedScene);

            _referencesToResolve.AddRange(allRelevantRefs);
        }
        /// <summary>
        /// Whenever another scene is loaded, we have another shot at resolving more cross-scene references
        /// </summary>
        /// <param name="sceneSetup">The AmsMultiSceneSetup that was loaded</param>
        private void HandleNewSceneLoaded(AmsMultiSceneSetup sceneSetup)
        {
            var loadedScene = sceneSetup.gameObject.scene;

            if (!loadedScene.isLoaded)
            {
                Debug.LogErrorFormat(this, "{0} Received HandleNewSceneLoaded from scene {1} which isn't considered loaded.  The scene MUST be considered loaded by this point", GetType().Name, loadedScene.name);
            }

            // Restore any references to this newly loaded scene
            foreach (var xRef in _crossSceneReferences)
            {
                if (!_referencesToResolve.Contains(xRef) && xRef.toScene.scene == loadedScene)
                {
                    _referencesToResolve.Add(xRef);
                }
            }

            if (_referencesToResolve.Count > 0)
            {
                AmsDebug.Log(this, "Scene {0} Loaded. {1} Cross-Scene References (in total) from Cross-Scene Manager in {2} are queued for resolve.", loadedScene.name, _referencesToResolve.Count, gameObject.scene.name);
                ConditionalResolveReferences(_referencesToResolve);
            }
        }
		/// <summary>
		/// Whenever a scene is destroyed, we will receive this callback.  In the editor, we can remember that we may be about to lose a cross-scene reference.
		/// </summary>
		/// <param name="sceneSetup"></param>
		private void HandleSceneDestroyed( AmsMultiSceneSetup sceneSetup )
		{
			var destroyedScene = sceneSetup.gameObject.scene;
			if ( !destroyedScene.IsValid() )
				return;

			// If our own scene is being destroyed, we don't need to do anymore work
			if ( destroyedScene == gameObject.scene )
				return;

			// Remove all of the pending refs for that scene.
			_referencesToResolve.RemoveAll( x => x.toScene.scene == destroyedScene );

			// Now we re-add all of the relevant refs to pending.  They'll be re-resolved when the scene is loaded again.
			var allRelevantRefs = _crossSceneReferences.Where( x => x.toScene.scene == destroyedScene );
			_referencesToResolve.AddRange( allRelevantRefs );
		}
		/// <summary>
		/// Whenever another scene is loaded, we have another shot at resolving more cross-scene references
		/// </summary>
		/// <param name="sceneSetup">The AmsMultiSceneSetup that was loaded</param>
		private void HandleNewSceneLoaded( AmsMultiSceneSetup sceneSetup )
		{
			var loadedScene = sceneSetup.gameObject.scene;
			if ( !loadedScene.isLoaded )
				Debug.LogErrorFormat( this, "{0} Received HandleNewSceneLoaded from scene {1} which isn't considered loaded.  The scene MUST be considered loaded by this point", GetType().Name, loadedScene.name );

			// Restore any references to this newly loaded scene
			foreach( var xRef in _crossSceneReferences )
			{
				if ( !_referencesToResolve.Contains(xRef) && xRef.toScene.scene == loadedScene )
					_referencesToResolve.Add( xRef );
			}

			if ( _referencesToResolve.Count > 0 )
			{
				AmsDebug.Log( this, "Scene {0} Loaded. {1} Cross-Scene References (in total) from Cross-Scene Manager in {2} are queued for resolve.", loadedScene.name, _referencesToResolve.Count, gameObject.scene.name );
				ConditionalResolveReferences( _referencesToResolve );
			}
		}