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
private static void HandleSavingScenes( IList<Scene> scenes ) { // We need to create an AmsMultiSceneSetup singleton in every scene. This is how we keep track of Awake scenes and // it also allows us to use cross-scene references. foreach( var scene in scenes ) { if ( !scene.isLoaded ) continue; var sceneSetup = GameObjectEx.GetSceneSingleton<AmsMultiSceneSetup>( scene, true ); sceneSetup.OnBeforeSerialize(); } }
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); }
/// <summary> /// When a scene is opened, determine if we must add an AmsMultiSceneSetup to it /// </summary> /// <param name="scene">The scene that was opened</param> /// <param name="mode">How it was opened</param> private static void EditorSceneManager_sceneOpened( Scene scene, OpenSceneMode mode ) { if ( !scene.isLoaded ) return; var sceneSetup = GameObjectEx.GetSceneSingleton<AmsMultiSceneSetup>( scene, false ); if ( !sceneSetup ) { sceneSetup = GameObjectEx.GetSceneSingleton<AmsMultiSceneSetup>( scene, true ); sceneSetup.transform.SetSiblingIndex(0); // Let's not mark it dirty as it doesn't need to be dirtied (really) as nothing's changed yet. //EditorSceneManager.MarkSceneDirty( scene ); } }
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 ); } }
/// <summary> /// Return the Singleton for a given scene (there is one per Scene). /// </summary> /// <param name="scene">The Scene to obtain the singleton for</param> /// <returns>The per-scene singleton</returns> public static AmsCrossSceneReferences GetSceneSingleton(Scene scene, bool bCreateIfNotFound) { var multiSceneSetup = GameObjectEx.GetSceneSingleton <AmsMultiSceneSetup>(scene, bCreateIfNotFound); if (!multiSceneSetup) { return(null); } var existing = multiSceneSetup.gameObject.GetComponent <AmsCrossSceneReferences>(); if (existing) { return(existing); } else if (bCreateIfNotFound) { return(multiSceneSetup.gameObject.AddComponent <AmsCrossSceneReferences>()); } return(null); }
private static void OnHierarchyWindowItemOnGUI(int instanceID, Rect selectionRect) { if (Application.isPlaying) { return; } // We can't early out because now we have widgets that respond to events. // We could potentially early-out on EventType.Used (which is used during scrolling). //if ( Event.current.type != EventType.Repaint ) // return; if (_justifyRightLabel == null) { _justifyRightLabel = new GUIStyle(GUI.skin.label); _justifyRightLabel.alignment = TextAnchor.UpperRight; _justifyRightLabel.richText = true; } if (_justifyRightPopup == null) { _justifyRightPopup = new GUIStyle(GUI.skin.FindStyle("Popup")); _justifyRightPopup.stretchWidth = false; _justifyRightPopup.alignment = TextAnchor.UpperRight; _justifyRightPopup.richText = true; } // Which object are we looking at? UnityEngine.Object obj = EditorUtility.InstanceIDToObject(instanceID); bool bIsSceneHeader = (instanceID != 0 && !obj); if (!bIsSceneHeader) { return; } // Make sure we have a scene var scene = GetSceneFromHandleID(instanceID); if (!scene.IsValid()) { return; } selectionRect.xMax -= 32.0f; // Now figure out what these scene settings are var activeScene = EditorSceneManager.GetActiveScene(); var sceneSetup = GameObjectEx.GetSceneSingleton <AmsMultiSceneSetup>(EditorSceneManager.GetActiveScene(), false); if (!sceneSetup) { GUI.Label(selectionRect, ColorText("AMS Not Found in " + activeScene.name, Color.red), _justifyRightLabel); return; } // If we're the active scene... if (activeScene == scene) { GUI.Label(selectionRect, ColorText("<b>Active</b>", Color.green), _justifyRightLabel); return; } var entries = sceneSetup.GetSceneSetup(); var entry = entries.FirstOrDefault(x => x.scene.editorPath == scene.path); if (entry == null) { GUI.Label(selectionRect, ColorText("(Not Managed)", Color.red), _justifyRightLabel); return; } if (entry.loadMethod == AmsMultiSceneSetup.LoadMethod.Additive || entry.loadMethod == AmsMultiSceneSetup.LoadMethod.AdditiveAsync) { var buildEntry = EditorBuildSettings.scenes.FirstOrDefault(x => x.path == scene.path); if (buildEntry == null || !buildEntry.enabled) { // Draw this next to the drop-down. Rect textRect = new Rect(selectionRect); textRect.xMax -= 100.0f; GUI.Label(textRect, ColorText("Not in Build", Color.red), _justifyRightLabel); } } EditorGUI.BeginChangeCheck(); selectionRect.xMin = selectionRect.xMax - 100.0f; EditorGUIUtility.GetControlID(FocusType.Passive); // This needs to happen in Unity 2018.x entry.loadMethod = (AmsMultiSceneSetup.LoadMethod)EditorGUI.EnumPopup(selectionRect, entry.loadMethod); if (EditorGUI.EndChangeCheck()) { EditorSceneManager.MarkSceneDirty(sceneSetup.gameObject.scene); } }