/// <param name="prefabStage">If not `null`, look for the mockup canvas on environment scene for editing a prefab **instead** of normal scenes.</param> private static void EnsureCanvasAndEventSetup(PrefabStage prefabStage = null) { //Create the hidden canvas if not already. bool prefabMode = prefabStage != null; var selectedMockupCanvas = prefabMode ? prefabMockupCanvas : mockupCanvas; if (selectedMockupCanvas == null) { //Find existing in the case of assembly reload //For some reason GameObject.FindObjectOfType could not get the canvas on main scene, it is active also, but by name works... var canvasObject = prefabMode ? prefabStage.stageHandle.FindComponentOfType <MockupCanvas>() : GameObject.Find(mockupCanvasName)?.GetComponent <MockupCanvas>(); if (canvasObject != null) { DebugTransitions($"[Notch Solution] Found existing (Prefab mode {prefabMode})"); } else { var prefabGuids = AssetDatabase.FindAssets(mockupCanvasName); if (prefabGuids.Length == 0) { return; } DebugTransitions($"[Notch Solution] Creating canvas (Prefab mode {prefabMode})"); GameObject mockupCanvasPrefab = AssetDatabase.LoadAssetAtPath <GameObject>(AssetDatabase.GUIDToAssetPath(prefabGuids.First())); var instantiated = prefabMode ? (GameObject)(PrefabUtility.InstantiatePrefab(mockupCanvasPrefab, prefabStage.scene)) : (GameObject)PrefabUtility.InstantiatePrefab(mockupCanvasPrefab); //It sometimes instantiated into null on script reloading when starting Unity? if (instantiated != null) { canvasObject = instantiated.GetComponent <MockupCanvas>(); instantiated.hideFlags = overlayCanvasFlag; if (Application.isPlaying) { DontDestroyOnLoad(canvasObject); } } canvasObject.PrefabStage = prefabMode; if (prefabMode) { prefabMockupCanvas = canvasObject; } else { mockupCanvas = canvasObject; } if (eventAdded == false) { eventAdded = true; //Add clean up event. EditorApplication.playModeStateChanged += PlayModeStateChangeAction; // EditorSceneManager.sceneClosing += (a, b) => // { // DebugTransitions($"Scene closing {a} {b}"); // }; // EditorSceneManager.sceneClosed += (a) => // { // DebugTransitions($"Scene closed {a}"); // }; // EditorSceneManager.sceneLoaded += (a, b) => // { // DebugTransitions($"Scene loaded {a} {b}"); // }; // EditorSceneManager.sceneUnloaded += (a) => // { // DebugTransitions($"Scene unloaded {a}"); // }; PrefabStage.prefabStageOpened += (ps) => { DebugTransitions($"Prefab opening {ps.scene.GetRootGameObjects().First().name} {ps.prefabContentsRoot.name}"); //On open prefab, the "dont save" objects on the main scene will disappear too. //So that we could still see it in the game view WHILE editing a prefab, we make it back. //Along with this the prefab mode canvas will also be updated. UpdateAllMockups(); //On entering prefab mode, the Notch Simulator panel did not get OnGUI(). UpdateSimulatorTargets(); }; PrefabStage.prefabStageClosing += (ps) => { DebugTransitions($"Prefab closing {ps.scene.GetRootGameObjects().First().name} {ps.prefabContentsRoot.name}"); //There is no problem on closing prefab stage, no need to restore the outer mockup. }; EditorSceneManager.sceneOpening += (a, b) => { DebugTransitions($"Scene opening {a} {b}"); DestroyHiddenCanvas(); }; EditorSceneManager.sceneOpened += (a, b) => { DebugTransitions($"Scene opened {a} {b}"); UpdateAllMockups(); }; void PlayModeStateChangeAction(PlayModeStateChange state) { DebugTransitions($"Changed state PLAY {EditorApplication.isPlaying} PLAY or WILL CHANGE {EditorApplication.isPlayingOrWillChangePlaymode}"); switch (state) { case PlayModeStateChange.EnteredEditMode: DebugTransitions($"Entered Edit {canvasObject}"); AddOverlayInPlayMode(); //For when coming back from play mode. break; case PlayModeStateChange.EnteredPlayMode: DebugTransitions($"Entered Play {canvasObject}"); break; case PlayModeStateChange.ExitingEditMode: DebugTransitions($"Exiting Edit {canvasObject}"); DestroyHiddenCanvas(); //Clean up the DontSave canvas we made in edit mode. break; case PlayModeStateChange.ExitingPlayMode: DebugTransitions($"Exiting Play {canvasObject}"); DestroyHiddenCanvas(); //Clean up the DontSave canvas we made in play mode. break; } } } } } }
private static void UpdateMockup() { bool enableSimulation = NotchSimulatorUtility.enableSimulation; //Create the hidden canvas if not already. if (canvasObject == null) { //Find existing in the case of assembly reload canvasObject = GameObject.Find(mockupCanvasName); if (canvasObject != null) { //Debug.Log($"Found existing"); mockupCanvas = canvasObject.GetComponent <MockupCanvas>(); } else { //Debug.Log($"Creating canvas"); var prefabGuids = AssetDatabase.FindAssets(mockupCanvasName); GameObject mockupCanvasPrefab = AssetDatabase.LoadAssetAtPath <GameObject>(AssetDatabase.GUIDToAssetPath(prefabGuids.First())); canvasObject = (GameObject)PrefabUtility.InstantiatePrefab(mockupCanvasPrefab); mockupCanvas = canvasObject.GetComponent <MockupCanvas>(); canvasObject.hideFlags = overlayCanvasFlag; if (Application.isPlaying) { DontDestroyOnLoad(canvasObject); } } if (eventAdded == false) { eventAdded = true; //Add clean up event. EditorApplication.playModeStateChanged += PlayModeStateChangeAction; // EditorSceneManager.sceneClosing += (a, b) => // { // Debug.Log($"Scene closing {a} {b}"); // }; // EditorSceneManager.sceneClosed += (a) => // { // Debug.Log($"Scene closed {a}"); // }; // EditorSceneManager.sceneLoaded += (a, b) => // { // Debug.Log($"Scene loaded {a} {b}"); // }; // EditorSceneManager.sceneUnloaded += (a) => // { // Debug.Log($"Scene unloaded {a}"); // }; EditorSceneManager.sceneOpening += (a, b) => { //Debug.Log($"Scene opening {a} {b}"); DestroyHiddenCanvas(); }; EditorSceneManager.sceneOpened += (a, b) => { //Debug.Log($"Scene opened {a} {b}"); UpdateMockup(); }; void PlayModeStateChangeAction(PlayModeStateChange state) { //Debug.Log($"Changed state PLAY {EditorApplication.isPlaying} PLAY or WILL CHANGE {EditorApplication.isPlayingOrWillChangePlaymode}"); switch (state) { case PlayModeStateChange.EnteredEditMode: //Debug.Log($"Entered Edit {canvasObject}"); AddOverlayInPlayMode(); //For when coming back from play mode. break; case PlayModeStateChange.EnteredPlayMode: //Debug.Log($"Entered Play {canvasObject}"); break; case PlayModeStateChange.ExitingEditMode: //Debug.Log($"Exiting Edit {canvasObject}"); DestroyHiddenCanvas(); //Clean up the DontSave canvas we made in edit mode. break; case PlayModeStateChange.ExitingPlayMode: //Debug.Log($"Exiting Play {canvasObject}"); DestroyHiddenCanvas(); //Clean up the DontSave canvas we made in play mode. break; } } } } if (enableSimulation) { //Landscape has an alias that turns ToString into LandscapeLeft lol var orientationString = NotchSimulatorUtility.GetGameViewOrientation() == ScreenOrientation.Landscape ? nameof(ScreenOrientation.Landscape) : nameof(ScreenOrientation.Portrait); SimulationDevice simDevice = NotchSimulatorUtility.selectedDevice; var name = $"{prefix}-{simDevice.ToString()}-{orientationString}"; var guids = AssetDatabase.FindAssets(name); var first = guids.FirstOrDefault(); if (first == default(string)) { throw new InvalidOperationException($"No mockup image named {name} in NotchSolution/Editor/Mockups folder!"); } Sprite mockupSprite = AssetDatabase.LoadAssetAtPath <Sprite>(AssetDatabase.GUIDToAssetPath(first)); mockupCanvas.Show(); mockupCanvas.SetMockupSprite(mockupSprite, NotchSimulatorUtility.GetGameViewOrientation(), simulate: enableSimulation, flipped: NotchSimulatorUtility.flipOrientation); } else { mockupCanvas.Hide(); } }