コード例 #1
0
        /// <summary>
        /// Start is executed just before the first Update (a frame after Awake/OnEnable).
        /// We execute the Scene loading here because Unity has issues loading scenes during the initial Awake/OnEnable calls.
        /// </summary>
        IEnumerator Start()
        {
            if (Application.isPlaying)
            {
                yield return(new WaitForEndOfFrame()); // This will always wait for at least one frame before control is returned.
            }

            AmsDebug.Log(this, "{0}.Start() Scene: {1}. Frame: {2}", GetType().Name, gameObject.scene.name, Time.frameCount);

            // Second chance at loading scenes
            if (_isMainScene)
            {
                LoadSceneSetup();
            }

#if UNITY_EDITOR
            // Make sure we update the settings every time we unload/load a Scene
            // This is strategically placed after the LoadSceneSetup().
            if (!EditorApplication.isPlaying)
            {
                EditorApplication.hierarchyChanged -= OnBeforeSerialize;
                EditorApplication.hierarchyChanged += OnBeforeSerialize;
            }
#endif
        }
コード例 #2
0
        private void ConditionalResolveReferences(List <RuntimeCrossSceneReference> references)
        {
            for (int i = references.Count - 1; i >= 0; --i)
            {
                var xRef = references[i];

                try
                {
                    var  fromScene = xRef.fromScene;
                    var  toScene   = xRef.toScene;
                    bool bIsReady  = fromScene.isLoaded && toScene.isLoaded;

                    AmsDebug.Log(this, "{0}.ConditionalResolveReferences() Scene: {1}. xRef: {2}. isReady: {3}. fromSceneLoaded: {4}. toSceneLoaded: {5}.", GetType().Name, gameObject.scene.name, xRef, bIsReady, fromScene.isLoaded, toScene.isLoaded);

                    if (bIsReady)
                    {
                        // Remove it from our list (assuming it goes through)
                        references.RemoveAt(i);

                        AmsDebug.Log(this, "Restoring Cross-Scene Reference {0}", xRef);
                        xRef.Resolve();

                        // Notify any listeners
                        if (CrossSceneReferenceRestored != null)
                        {
                            CrossSceneReferenceRestored(xRef);
                        }
                    }
                }
                catch (System.Exception ex)
                {
                    Debug.LogException(ex, this);
                }
            }
        }
コード例 #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 (!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);
            }
        }
コード例 #4
0
        public Object   EditorResolveSlow(bool bLoadScene)
        {
            var scene = this.scene.scene;

            if (!scene.IsValid())
            {
                return(null);
            }

            if (!scene.isLoaded)
            {
                if (!bLoadScene)
                {
                    return(null);
                }

                EditorSceneManager.LoadScene(scene.path);
            }

            AmsDebug.LogError(null, "Performing EditorResolveSlow but it was never tested");

            // Find the object (this is potentially very slow).
            Object[] allObjs = EditorUtility.CollectDeepHierarchy(scene.GetRootGameObjects());
            foreach (var obj in allObjs)
            {
                if (editorLocalId == Unsupported.GetLocalIdentifierInFile(obj.GetInstanceID()))
                {
                    return(obj);
                }
            }

            return(null);
        }
コード例 #5
0
        /// <summary>
        /// Start is executed just before the first Update (a frame after Awake/OnEnable).
        /// We execute the Scene loading here because Unity has issues loading scenes during the initial Awake/OnEnable calls.
        /// </summary>
        void Start()
        {
            AmsDebug.Log(this, "{0}.Start() Scene: {1}. Frame: {2}", GetType().Name, gameObject.scene.name, Time.frameCount);

            // Notify any listeners (like the cross-scene referencer)
            if (OnStart != null)
            {
                OnStart(this);
            }

            // Second chance at loading scenes
            if (_isMainScene)
            {
                LoadSceneSetup();
            }

#if UNITY_EDITOR
            // Make sure we update the settings every time we unload/load a Scene
            // This is strategically placed after the LoadSceneSetup().
            if (!EditorApplication.isPlaying)
            {
#if UNITY_2018
                EditorApplication.hierarchyChanged -= OnHierarchyChanged;
                EditorApplication.hierarchyChanged += OnHierarchyChanged;
#else
                EditorApplication.hierarchyWindowChanged -= OnHierarchyChanged;
                EditorApplication.hierarchyWindowChanged += OnHierarchyChanged;
#endif
            }
#endif
        }
コード例 #6
0
        /// <summary>
        /// Awake can be used to tell anyone that a Scene has just been loaded.
        /// Due to a bug in PostProcessScene, this is the first thing to occur in a loaded scene.
        /// </summary>
        void Awake()
        {
            AmsDebug.Log(this, "{0}.Awake() (Scene {1}). IsLoaded: {2}. Frame: {3}", GetType().Name, gameObject.scene.name, gameObject.scene.isLoaded, Time.frameCount);

#if UNITY_EDITOR
            if (!BuildPipeline.isBuildingPlayer)
            {
                _thisScenePath = gameObject.scene.path;
            }
#endif

            // Notify any listeners we're now awake
            if (OnAwake != null)
            {
                OnAwake(this);
            }

            if (_isMainScene)
            {
                if (!Application.isEditor || gameObject.scene.isLoaded || Time.frameCount > 1)
                {
                    LoadSceneSetup();
                }
            }
        }
コード例 #7
0
        void Awake()
        {
            AmsDebug.Log(this, "{0}.Awake() Scene: {1}. Path: {2}. Frame: {3}. Root Count: {4}", GetType().Name, gameObject.scene.name, gameObject.scene.path, Time.frameCount, gameObject.scene.rootCount);

            _referencesToResolve.Clear();
            _referencesToResolve.AddRange(_crossSceneReferences);

            StartCoroutine(CoWaitForSceneLoadThenResolveReferences(gameObject.scene));
        }
コード例 #8
0
        /// <summary>
        /// Resolve a cross-scene reference if possible.
        /// </summary>
        /// <returns>The cross-scene referenced object if it's possible</returns>
        private Object  RuntimeResolve()
        {
            var scene = this.scene.scene;

            if (!scene.IsValid())
            {
                return(null);
            }

            // Try to find the Object with our custom method that checks only the subscene
            GameObject gameObject = GameObjectEx.FindBySceneAndPath(scene, fullPath);

            // If that fails, we can try using Unity's GameObject.Find in case the user has switched it on us, or
            // in the case that's it's in a DontDestroyOnLoad scene
            if (!gameObject)
            {
                gameObject = GameObject.Find(fullPath);

                // It's truly failed
                if (!gameObject)
                {
                    return(null);
                }
                else
                {
                    AmsDebug.LogWarning(gameObject, "UniqueObject '{0}' resolved unexpected to '{1}'{2}.  Did you move it manually?", this, gameObject.scene.name, gameObject.GetFullName());
                }
            }

            if (string.IsNullOrEmpty(componentName))
            {
                return(gameObject);
            }

            // This is the old method where we didn't store the component index (deprecated)
            if (version < 1)
            {
                Component oldStyleComponent = gameObject.GetComponent(componentName);
                if (componentIndex < 0 || oldStyleComponent)
                {
                    return(oldStyleComponent);
                }
            }

            // Get the component and index
            System.Type type = System.Type.GetType(componentName, false);
            if (type != null)
            {
                gameObject.GetComponents(type, _reusableComponentsList);
                if (componentIndex < _reusableComponentsList.Count)
                {
                    return(_reusableComponentsList[componentIndex]);
                }
            }

            return(null);
        }
コード例 #9
0
        /// <summary>
        /// Start is executed just before the first Update (a frame after Awake/OnEnable).
        /// We execute the Scene loading here because Unity has issues loading scenes during the initial Awake/OnEnable calls.
        /// </summary>
        void Start()
        {
            AmsDebug.Log(this, "{0}.Start() Scene: {1}. Frame: {2}", GetType().Name, gameObject.scene.name, Time.frameCount);

            // Notify any listeners (like the cross-scene referencer)
            if (OnStart != null)
            {
                OnStart(this);
            }

            // Second chance at loading scenes
            LoadSceneSetup();
        }
コード例 #10
0
		public bool IsSameSource( RuntimeCrossSceneReference other )
		{
			try
			{
				return (this.fromObject == other.fromObject) && (this._sourceField == other._sourceField);
			}
			catch ( System.Exception ex )
			{
				AmsDebug.Log( null, "IsSameSource: Could not compare: {0} and {1}: {2}", ToString(), other, ex );
			}

			return false;
		}
コード例 #11
0
        private void MergeScene(SceneEntry entry)
        {
            var scene = entry.scene.scene;

            // Make sure there is only ever one AmsMultiSceneSetup in a given scene
            var sourceSetup = GameObjectEx.GetSceneSingleton <AmsMultiSceneSetup>(scene, false);

            if (sourceSetup)
            {
                GameObject.Destroy(sourceSetup.gameObject);
            }

            AmsDebug.Log(this, "Merging {0} into {1}", scene.path, gameObject.scene.path);
            SceneManager.MergeScenes(scene, gameObject.scene);
        }
コード例 #12
0
        void Awake()
        {
            AmsDebug.Log(this, "{0}.Awake() Scene: {1}. IsLoaded: {2}. Path: {3}. Frame: {4}. Root Count: {5}", GetType().Name, gameObject.scene.name, gameObject.scene.isLoaded, gameObject.scene.path, Time.frameCount, gameObject.scene.rootCount);

            // Upgrade us (we upgraded the Cross-Scene Reference data)
            // This may freak out users on their first run since it will look like their cross-scene references are gone
            // In reality, they are just in the scene, ready to be re-created on save
            if (_version < CurrentSerializedVersion)
            {
                int numCrossSceneRefs = _crossSceneReferences.Count;
                ConditionalResolveReferences(_crossSceneReferences);

                if (numCrossSceneRefs != _crossSceneReferences.Count)
                {
                    AmsDebug.LogWarning(this, "{0} was upgraded. {1} cross-scene references will be re-created on next save.", name, numCrossSceneRefs - _crossSceneReferences.Count);
                }
                else
                {
                    AmsDebug.LogWarning(this, "{0} needs upgrading.  Please resave {1}", name, gameObject.scene.name);
                }

#if UNITY_EDITOR
                if (!Application.isPlaying)
                {
                    GameObject gameObject = this.gameObject;
                    EditorApplication.delayCall += () => { if (gameObject)
                                                           {
                                                               EditorSceneManager.MarkSceneDirty(gameObject.scene);
                                                           }
                    };
                }
#endif
            }

            // Make sure we keep track of all of the merged scenes
            AmsSceneReference thisScene = new AmsSceneReference(gameObject.scene);
            foreach (var prevScene in _mergedScenes)
            {
                _activeMergedScenes.Add(prevScene, thisScene);
            }

            // We need to queue our cross-scene references super early in case we get merged.
            _referencesToResolve.Clear();
            _referencesToResolve.AddRange(_crossSceneReferences);

            // We should be able to merge our cross-scene references to any other loaded scene here.
            ResolvePendingCrossSceneReferences();
        }
コード例 #13
0
        void Start()
        {
            AmsDebug.Log(this, "{0}.Start() Scene: {1}. IsLoaded: {2}. Path: {3}. Frame: {4}. Root Count: {5}", GetType().Name, gameObject.scene.name, gameObject.scene.isLoaded, gameObject.scene.path, Time.frameCount, gameObject.scene.rootCount);

            // A build might have just been performed, in that case clean-up the leftovers.
            PerformPostBuildCleanup();

            // For some reason in Awake(), the scene we belong to isn't considered "loaded"?!  We've tried to work around that, but if it failed, try again here.
            ResolvePendingCrossSceneReferences();

            // Register to these callbacks only once
            AmsMultiSceneSetup.OnStart     -= HandleNewSceneLoaded;
            AmsMultiSceneSetup.OnStart     += HandleNewSceneLoaded;
            AmsMultiSceneSetup.OnDestroyed -= HandleSceneDestroyed;
            AmsMultiSceneSetup.OnDestroyed += HandleSceneDestroyed;
        }
コード例 #14
0
        void Start()
        {
            AmsDebug.Log(this, "{0}.Start() Scene: {1}. Path: {2}. Frame: {3}. Root Count: {4}", GetType().Name, gameObject.scene.name, gameObject.scene.path, Time.frameCount, gameObject.scene.rootCount);

            // A build might have just been performed, in that case clean-up the leftovers.
            PerformPostBuildCleanup();

            if (Application.isPlaying)
            {
                // Give us a second chance (helps initial load of scene)
                // For some reason in Awake(), the scene we belong to isn't considered "loaded"?!
                // Unfortunately we can get a Start() before CoWaitForSceneLoadThenResolveReferences finishes... so we need to nuke it if it's still running.
                StopAllCoroutines();
                ResolvePendingCrossSceneReferences();
            }
        }
コード例 #15
0
        /// <summary>
        /// Loads a particular Scene Entry in the Editor
        /// </summary>
        /// <param name="entry">The entry to load</param>
        private void LoadEntryInEditor(SceneEntry entry)
        {
            // Bad time to do this.
            if (EditorApplication.isPlayingOrWillChangePlaymode && !EditorApplication.isPlaying)
            {
                return;
            }

            // We can't do this
            if (string.IsNullOrEmpty(entry.scene.editorPath) || entry.scene.editorPath == gameObject.scene.path)
            {
                return;
            }

            bool bShouldLoad = entry.loadInEditor && AmsPreferences.AllowAutoload;
            var  scene       = entry.scene.scene;

            try
            {
                if (!scene.IsValid())
                {
                    if (bShouldLoad)
                    {
                        AmsDebug.Log(this, "Scene {0} is loading Scene {1} in Editor", gameObject.scene.name, entry.scene.name);
                        EditorSceneManager.OpenScene(entry.scene.editorPath, OpenSceneMode.Additive);
                    }
                    else
                    {
                        AmsDebug.Log(this, "Scene {0} is opening Scene {1} (without loading) in Editor", gameObject.scene.name, entry.scene.name);
                        EditorSceneManager.OpenScene(entry.scene.editorPath, OpenSceneMode.AdditiveWithoutLoading);
                    }
                }
                else if (bShouldLoad != scene.isLoaded)
                {
                    if (bShouldLoad && !scene.isLoaded)
                    {
                        AmsDebug.Log(this, "Scene {0} is loading existing Scene {1} in Editor", gameObject.scene.name, entry.scene.name);
                        EditorSceneManager.OpenScene(entry.scene.editorPath, OpenSceneMode.Additive);
                    }
                    else
                    {
                        AmsDebug.Log(this, "Scene {0} is closing Scene {1} in Editor", gameObject.scene.name, entry.scene.name);
                        EditorSceneManager.CloseScene(scene, false);
                    }
                }
            } catch (System.Exception ex) { Debug.LogException(ex, this); }
        }
コード例 #16
0
        void PerformPostBuildCleanup()
        {
            if (Application.isEditor && !Application.isPlaying && _realSceneRootsForPostBuild.Count > 0)
            {
                GameObject[] newSceneRoots = gameObject.scene.GetRootGameObjects();
                foreach (GameObject root in newSceneRoots)
                {
                    if (!_realSceneRootsForPostBuild.Contains(root))
                    {
                        AmsDebug.LogWarning(this, "Destroying '{0}/{1}' since we've determined it's a temporary for a cross-scene reference", gameObject.scene.name, root.name);
                        DestroyImmediate(root);
                    }
                }

                _realSceneRootsForPostBuild.Clear();
            }
        }
コード例 #17
0
        /// <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);
        }
コード例 #18
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 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);
            }
        }
コード例 #20
0
        private void ConditionalResolveReferences(List <RuntimeCrossSceneReference> references)
        {
            var fromScene = gameObject.scene;

            for (int i = references.Count - 1; i >= 0; --i)
            {
                var xRef = references[i];

                if (!xRef.fromObject)
                {
                    AmsDebug.LogWarning(this, "Missing Source Object for xRef at (possible index) {0}: {1}", i, xRef);
                    continue;
                }

                try
                {
                    // See if it's a reference to a merged scene... if so we need to redirect
                    var toScene = xRef.toScene;
                    if (!toScene.IsValid())
                    {
                        AmsSceneReference mergedSceneRedirect;
                        if (_activeMergedScenes.TryGetValue(toScene, out mergedSceneRedirect))
                        {
                            AmsDebug.Log(this, "Redirecting cross scene reference {0} from original target scene {1} to scene {2}", xRef, toScene.name, mergedSceneRedirect.name);
                            toScene      = mergedSceneRedirect;
                            xRef.toScene = mergedSceneRedirect;
                        }
                    }

                    // Debug information
                    AmsDebug.Log(this, "{0}.ConditionalResolveReferences() Scene: {1}. xRef: {2}. fromSceneLoaded: {3}. toSceneLoaded: {4}.", GetType().Name, fromScene.name, xRef, fromScene.isLoaded, toScene.isLoaded);

                    if (toScene.isLoaded)
                    {
                        // Remove it from our list (assuming it goes through)
                        references.RemoveAt(i);

                        AmsDebug.Log(this, "Restoring Cross-Scene Reference {0}", xRef);
                        AmsCrossSceneReferenceResolver.Resolve(xRef);

                        // Notify any listeners
                        if (CrossSceneReferenceRestored != null)
                        {
                            CrossSceneReferenceRestored(xRef);
                        }
                    }
                }
                catch (ResolveException ex)
                {
                    string message = ex.Message;

                    // Make it easier for us to find where the cross-scene reference is
                    Object context = xRef.fromObject;
                    if (!context)
                    {
                        context = this;
                    }

                    Debug.LogErrorFormat(context, "{0} in {1}: {2}", GetType().Name, gameObject.scene.name, message);
                }
                catch (System.Exception ex)
                {
                    Debug.LogException(ex, this);
                }
            }
        }
コード例 #21
0
        /// <summary>
        /// Load a particular Scene Entry
        /// </summary>
        /// <param name="entry">The Entry to load</param>
        private void LoadEntryAtRuntime(SceneEntry entry)
        {
            // Don't load
            if (entry.loadMethod == LoadMethod.DontLoad)
            {
                return;
            }

            // Already loaded, try editor first
            var existingScene = SceneManager.GetSceneByPath(entry.scene.editorPath);

            // Try runtime path
            if (!existingScene.IsValid())
            {
                existingScene = SceneManager.GetSceneByPath(entry.scene.runtimePath);
            }

#if UNITY_EDITOR
            // Could be we just created the scene because it's baked
            if (!existingScene.IsValid())
            {
                existingScene = SceneManager.GetSceneByName(entry.scene.runtimePath);
            }

            if (Application.isEditor && entry.loadMethod == LoadMethod.Baked)
            {
                // If we've already processed this, return early
                if (_bakedScenesLoading.Contains(entry) || _bakedScenesMerged.Contains(entry))
                {
                    return;
                }

                // We're loading this entry, don't allow this to be re-entrant
                _bakedScenesLoading.Add(entry);

                if (!existingScene.IsValid())
                {
                    // This allows us to load the level even in playmode
                    EditorApplication.LoadLevelAdditiveInPlayMode(entry.scene.editorPath);
                }

                // Loading a scene can take multiple frames so we have to wait.
                // Baking scenes can only take place when they're all loaded due to cross-scene referencing
                if (_waitingToBake != null)
                {
                    StopCoroutine(_waitingToBake);
                }

                _waitingToBake = StartCoroutine(CoWaitAndBake());
                return;
            }
#endif

            // If it's already loaded, return early
            if (existingScene.IsValid())
            {
                return;
            }

            if (entry.loadMethod == LoadMethod.AdditiveAsync)
            {
                AmsDebug.Log(this, "Loading {0} Asynchronously from {1}", entry.scene.name, gameObject.scene.name);
                entry.asyncOp = SceneManager.LoadSceneAsync(entry.scene.runtimePath, LoadSceneMode.Additive);
                return;
            }

            if (entry.loadMethod == LoadMethod.Additive)
            {
                AmsDebug.Log(this, "Loading {0} from {1}", entry.scene.name, gameObject.scene.name);
                SceneManager.LoadScene(entry.scene.runtimePath, LoadSceneMode.Additive);
                return;
            }
        }
コード例 #22
0
        public static void OnSceneSaving(Scene scene, string path)
        {
            if (!scene.IsValid() || !scene.isLoaded)
            {
                return;
            }

            var instance = scene.GetSceneSingleton <AmsMultiSceneSetup>(true);

            if (!instance)
            {
                return;
            }

            instance.OnBeforeSerialize();

            bool isSceneSetupManual = instance._sceneSetupMode == SceneSetupManagement.Manual;

            if (isSceneSetupManual)
            {
                return;
            }

            // Clear if we're disabled... by implicitly never setting any values
            var  newSceneSetup = new List <SceneEntry>();
            bool bForceDirty   = false;

            // We only update the scene setup if we're the active scene
            var  activeScene      = SceneManager.GetActiveScene();
            bool isSceneSetupAuto = instance._sceneSetupMode == SceneSetupManagement.Automatic && (activeScene == scene);

            if (isSceneSetupAuto)
            {
                // Update our scene setup
                SceneSetup[] editorSceneSetup = EditorSceneManager.GetSceneManagerSetup();
                for (int i = 0; i < editorSceneSetup.Length; ++i)
                {
                    // If we're the active scene, don't save it.
                    var editorEntry = editorSceneSetup[i];
                    if (editorEntry.path == activeScene.path)
                    {
                        continue;
                    }

                    var newEntry = new SceneEntry(editorEntry);
                    newSceneSetup.Add(newEntry);

                    // Save the baked settings
                    var oldEntry = instance._sceneSetup.Find(x => newEntry.scene.Equals(x.scene));
                    if (oldEntry != null)
                    {
                        newEntry.loadMethod = oldEntry.loadMethod;

                        // We need to update the path if the runtime paths aren't the same (implies a rename)
                        bForceDirty = bForceDirty || (newEntry.scene.runtimePath != oldEntry.scene.runtimePath);
                    }
                }
            }

            // If we had a new scene setup...
            if (bForceDirty || !newSceneSetup.SequenceEqual(instance._sceneSetup))
            {
                instance._sceneSetup = newSceneSetup;
                EditorUtility.SetDirty(instance);
                EditorSceneManager.MarkSceneDirty(scene);

                AmsDebug.Log(instance, "SceneSetup for {0} has been updated. If this is unexpected, click here to double-check the entries!", activeScene.name);
            }
        }