static void RestoreCrossSceneReferences() { Scene activeScene = new Scene(); AmsMultiSceneSetup activeSetup = null; List<AmsMultiSceneSetup.SceneEntry> bakedScenes = new List<AmsMultiSceneSetup.SceneEntry>(); GetCommonParameters( ref activeScene, ref activeSetup, bakedScenes ); if ( bakedScenes.Count < 1 ) return; AmsDebug.Log( null, "Running RestoreCrossSceneReferences on Scene {0}", activeScene.name ); // Do the merge (bake) var targetCrossRefs = AmsCrossSceneReferences.GetSceneSingleton( activeScene, false ); if ( targetCrossRefs ) targetCrossRefs.ResolvePendingCrossSceneReferences(); foreach( var entry in bakedScenes ) { if ( !entry.scene.isLoaded ) { AmsDebug.LogError( activeSetup, "Could not restore cross-scene references for non-loaded scene: {0}", entry.scene.name ); continue; } var sourceCrossRefs = AmsCrossSceneReferences.GetSceneSingleton( entry.scene.scene, false ); if ( sourceCrossRefs ) sourceCrossRefs.ResolvePendingCrossSceneReferences(); } }
static void MergeScenes() { Scene activeScene = new Scene(); AmsMultiSceneSetup activeSetup = null; List<AmsMultiSceneSetup.SceneEntry> bakedScenes = new List<AmsMultiSceneSetup.SceneEntry>(); GetCommonParameters( ref activeScene, ref activeSetup, bakedScenes ); if ( bakedScenes.Count < 1 ) return; AmsDebug.Log( null, "Running MergeScenes on Scene {0}", activeScene.name ); foreach( var entry in bakedScenes ) { if ( !entry.scene.isLoaded ) { AmsDebug.LogError( activeSetup, "Could not merge non-loaded scene: {0}", entry.scene.name ); continue; } var sourceCrossRefs = AmsCrossSceneReferences.GetSceneSingleton( entry.scene.scene, false ); if ( sourceCrossRefs ) GameObject.DestroyImmediate( sourceCrossRefs.gameObject, false ); AmsDebug.Log( null, "Merging {0} into {1}", entry.scene.name, activeScene.name ); EditorSceneManager.MergeScenes( entry.scene.scene, activeScene ); } } // MergeScenes
static void MergeScenes() { Scene activeScene = new Scene(); AmsMultiSceneSetup activeSetup = null; List<AmsMultiSceneSetup.SceneEntry> bakedScenes = new List<AmsMultiSceneSetup.SceneEntry>(); GetCommonParameters( ref activeScene, ref activeSetup, bakedScenes ); if ( bakedScenes.Count < 1 ) return; AmsDebug.Log( null, "Running AMS MergeScenes on Scene {0} ({1})", activeScene.name, activeSetup.scenePath ); foreach( var entry in bakedScenes ) { if ( !entry.scene.isLoaded ) { AmsDebug.LogError( activeSetup, "Could not merge non-loaded scene: {0}", entry.scene.name ); continue; } // Merge the cross-scene references (and keep track of the merges) var bakedSceneSetup = GameObjectEx.GetSceneSingleton<AmsMultiSceneSetup>( entry.scene.scene, false ); if ( bakedSceneSetup ) AmsCrossSceneReferences.EditorBuildPipelineMergeScene( bakedSceneSetup, activeSetup ); AmsDebug.Log( null, "Running Unity MergeScenes for {0} into {1}", entry.scene.name, activeScene.name ); EditorSceneManager.MergeScenes( entry.scene.scene, activeScene ); } } // MergeScenes
public override void OnInspectorGUI() { AmsMultiSceneSetup target = (AmsMultiSceneSetup)this.target; // Help give us better hints at what the different SceneSetup modes refer to... if (target.sceneSetupMode == AmsMultiSceneSetup.SceneSetupManagement.Automatic) { bool isActiveScene = (SceneManager.GetActiveScene() == target.gameObject.scene); if (isActiveScene) { EditorGUILayout.HelpBox("Scene Setup is automatically generated and saved with the scene based on the hierarchy.", MessageType.Info); } else { EditorGUILayout.HelpBox("Scene Setup will not be updated or saved unless this Scene is set as Active", MessageType.Warning); } if (target.GetSceneSetup().Count < 1) { DrawPropertiesExcluding(serializedObject, "m_Script", "_sceneSetup"); EditorGUILayout.HelpBox("This scene was never saved as the Active Scene.\nTherefore this Scene will not auto-load other scenes.", MessageType.Info); } else { DrawPropertiesExcluding(serializedObject, "m_Script"); } } else if (target.sceneSetupMode == AmsMultiSceneSetup.SceneSetupManagement.Manual) { EditorGUILayout.HelpBox("Scene Setup will not changed unless you modify it manually (or change Scene Setup Mode).", MessageType.Info); DrawPropertiesExcluding(serializedObject, "m_Script"); } else { EditorGUILayout.HelpBox("Scene Setup will not be saved", MessageType.Warning); DrawPropertiesExcluding(serializedObject, "m_Script", "_sceneSetup"); } EditorGUILayout.HelpBox("Note: This behaviour is always required for cross-scene referencing to work.", MessageType.Info); // Since we're not using SerializedProperties, we need to update the SerializedObject ourselves. serializedObject.ApplyModifiedProperties(); serializedObject.Update(); // If anything changed, we should resetup the SceneSetup and repaint the hierarchy if (GUI.changed) { AmsMultiSceneSetup.OnSceneSaving(target.gameObject.scene, target.scenePath); EditorApplication.RepaintHierarchyWindow(); } }
static void WarnOnAllMissingCrossSceneRefs() { Scene activeScene = new Scene(); AmsMultiSceneSetup activeSetup = null; List<AmsMultiSceneSetup.SceneEntry> bakedScenes = new List<AmsMultiSceneSetup.SceneEntry>(); GetCommonParameters( ref activeScene, ref activeSetup, bakedScenes ); if ( !activeSetup ) return; var crossSceneReferences = activeScene.GetSceneSingleton<AmsCrossSceneReferences>( false ); if ( crossSceneReferences && crossSceneReferences.EditorWarnOnUnresolvedCrossSceneReferences() ) { Debug.LogWarningFormat( "Previous Cross-Scene Reference Errors were in {0}", activeSetup.scenePath ); } }
internal static void LoadScenesForMerging() { Scene activeScene = new Scene(); AmsMultiSceneSetup activeSetup = null; List<AmsMultiSceneSetup.SceneEntry> bakedScenes = new List<AmsMultiSceneSetup.SceneEntry>(); GetCommonParameters( ref activeScene, ref activeSetup, bakedScenes ); if ( bakedScenes.Count < 1 ) return; AmsDebug.Log( null, "Running LoadScenesForBaking on Scene {0}", activeScene.name ); // Now load all of the scenes foreach( var entry in bakedScenes ) { var realScene = entry.scene.scene; if ( !realScene.IsValid() ) { // This is good. This means it's not loaded yet. realScene = EditorSceneManager.OpenScene( entry.scene.editorPath, OpenSceneMode.Additive ); if ( !realScene.IsValid() ) { AmsDebug.LogError( activeSetup, "BakeScene: Scene {0} ({1}) referenced from Multi-Scene Setup in {2} is invalid.", entry.scene.editorPath, entry.scene.name, activeScene.name ); continue; } } // Let's catch this... if ( !realScene.isLoaded ) { realScene = EditorSceneManager.OpenScene( realScene.path, OpenSceneMode.Additive ); // if we're still not loaded, we're probably in trouble. if ( !realScene.isLoaded ) { AmsDebug.LogError( activeSetup, "BakeScene: Scene {0} ({1}) referenced from Multi-Scene Setup in {2} could not load.", entry.scene.editorPath, entry.scene.name, activeScene.name ); continue; } } } }
private static void GetCommonParameters( ref Scene activeScene, ref AmsMultiSceneSetup activeSceneSetup, List<AmsMultiSceneSetup.SceneEntry> bakedScenes ) { // We can only execute this when building the player. Otherwise we expect entries to already be in the scene. if ( !BuildPipeline.isBuildingPlayer ) return; // Get the SceneSetup for the Active Scene. activeScene = EditorSceneManager.GetActiveScene(); activeSceneSetup = GameObjectEx.GetSceneSingleton<AmsMultiSceneSetup>( activeScene, false ); if ( !activeSceneSetup ) return; var scenesInSetup = activeSceneSetup.GetSceneSetup(); foreach( var entry in scenesInSetup ) { bool bShouldBake = entry.loadMethod == AmsMultiSceneSetup.LoadMethod.Baked; if ( bShouldBake ) bakedScenes.Add( entry ); } }
public override void OnInspectorGUI() { AmsMultiSceneSetup target = (AmsMultiSceneSetup)this.target; if (!target.isMainScene) { DrawPropertiesExcluding(serializedObject, "m_Script", "_sceneSetup"); EditorGUILayout.HelpBox("Since we are not configured as a Main Scene, we will NOT keep track of loaded scenes.\nThis behaviour is still required for cross-scene referencing to work.", MessageType.Info); } else { DrawPropertiesExcluding(serializedObject, "m_Script"); } serializedObject.ApplyModifiedProperties(); serializedObject.Update(); if (GUI.changed) { EditorApplication.RepaintHierarchyWindow(); } }