/// <summary> /// Captures the resolution texture. /// </summary> IEnumerator CaptureResolutionTextureCoroutine(ScreenshotResolution resolution, CaptureMode captureMode, int antiAliasing, ColorFormat colorFormat) { // Init texture m_Texture = GetOrCreateTexture(resolution, colorFormat, captureMode == CaptureMode.FIXED_GAMEVIEW ? true : false); if (captureMode == CaptureMode.GAMEVIEW_RESIZING) { // Debug.Log ("Resize "); // Force screen size change GameViewController.SetGameViewSize(m_Texture.width, m_Texture.height); yield return(new WaitForEndOfFrame()); // Force wait if (!Application.isPlaying) { // Useless texture update in editor mode when game is not running, // that takes some computational times to be sure that the UI is updated at least one time before the capture if (MultiDisplayUtils.IsMultiDisplay()) { yield return(MultiDisplayCopyRenderBufferToTextureCoroutine(m_Texture)); } else { CopyScreenToTexture(m_Texture); } } // Delegate call to notify screen is resized onResolutionScreenResizedDelegate(resolution); // Wait several frames // Particularly needed for special effects using several frame to compute their effects, like temporal anti aliasing if (m_GameViewResizingWaitingMode == GameViewResizingWaitingMode.FRAMES || !Application.isPlaying) { for (int i = 0; i < m_GameViewResizingWaitingFrames; ++i) { // Debug.Log ("Wait " + i); //GameViewController.SetGameViewSize(m_Texture.width, m_Texture.height); #if UNITY_EDITOR if (!Application.isPlaying) { GameViewUtils.GetGameView().Repaint(); } #endif yield return(new WaitForEndOfFrame()); #if UNITY_EDITOR if (!Application.isPlaying && i < 2) { CopyScreenToTexture(m_Texture); // Useless update to force waiting for the gamview to be correctly updated } #endif // Debug.Log ("Wait " + i + " end"); } } else { #if (UNITY_5_4_OR_NEWER) yield return(new WaitForSecondsRealtime(m_GameViewResizingWaitingTime)); #else if (Time.timeScale > 0f) { yield return(new WaitForSeconds(m_GameViewResizingWaitingTime)); } #endif yield return(new WaitForEndOfFrame()); } // Debug.Log ("Capture"); // Capture the screen content if (MultiDisplayUtils.IsMultiDisplay()) { yield return(MultiDisplayCopyRenderBufferToTextureCoroutine(m_Texture)); } else { CopyScreenToTexture(m_Texture); } // Debug.Log ("End Capture"); } else if (captureMode == CaptureMode.RENDER_TO_TEXTURE) { // Wait for the end of rendering yield return(new WaitForEndOfFrame()); /* #if UNITY_EDITOR * if (Application.isPlaying) { * yield return new WaitForEndOfFrame (); * } else { * // We need to force a gameview repaint * Vector2 current = GameViewController.GetCurrentGameViewSize (); * GameViewController.SetGameViewSize ((int)current.x, (int)current.y); * yield return new WaitForEndOfFrame (); * } #endif */ // Do not need to wait anything, just capture the cameras RenderTexture renderTexture = GetOrCreateRenderTexture(resolution, antiAliasing); RenderCamerasToTexture(m_Cameras, m_Texture, renderTexture); } else if (captureMode == CaptureMode.FIXED_GAMEVIEW) { #if UNITY_EDITOR // Force repaint in case the gameview is not focus to prevent a lock if (!Application.isPlaying) { GameViewUtils.GetGameView().Repaint(); } #endif // Wait for the end of rendering yield return(new WaitForEndOfFrame()); // Capture the screen content if (MultiDisplayUtils.IsMultiDisplay()) { yield return(MultiDisplayCopyRenderBufferToTextureCoroutine(m_Texture)); } else { CopyScreenToTexture(m_Texture); } } // Alpha mask // if (colorFormat == ColorFormat.RGBA && recomputeAlphaMask) // { // // Capture the screen content // yield return StartCoroutine(RecomputeAlphaMask(resolution, m_Cameras, captureMode)); // } }
public IEnumerator CaptureAllCoroutine(List <ScreenshotResolution> resolutions, List <ScreenshotCamera> cameras, List <ScreenshotOverlay> overlays, CaptureMode captureMode, int antiAliasing = 8, bool captureGameUI = true, ColorFormat colorFormat = ColorFormat.RGB, bool recomputeAlphaMask = false, bool stopTime = false, bool restore = true) { // Debug.Log ("Capture all"); if (resolutions == null) { Debug.LogError("Resolution list is null."); yield break; } if (cameras == null) { Debug.LogError("Cameras list is null."); yield break; } if (cameras.Count == 0 && captureMode == CaptureMode.RENDER_TO_TEXTURE) { cameras.Add(new ScreenshotCamera(Camera.main)); } if (overlays == null) { Debug.LogError("Overlays list is null."); yield break; } if (captureMode == CaptureMode.RENDER_TO_TEXTURE && !UnityVersion.HasPro()) { Debug.LogError("RENDER_TO_TEXTURE requires Unity Pro or Unity 5.0 and later."); yield break; } // If a capture is in progress we wait until we can take the screenshot if (m_IsRunning == true) { Debug.LogWarning("A capture process is already running."); } while (m_IsRunning == true) { yield return(null); } #if (!UNITY_EDITOR && !UNITY_STANDALONE_WIN) if (captureMode == CaptureMode.GAMEVIEW_RESIZING) { Debug.LogError("GAMEVIEW_RESIZING capture mode is only available for Editor and Windows Standalone."); yield break; } #endif // Init m_IsRunning = true; // Stop the time so all screenshots are exactly the same if (Application.isPlaying && stopTime) { StopTime(); } // Apply settings: enable and disable the cameras and canvas ApplySettings(cameras, overlays, captureMode, captureGameUI); // Save the screen config to be restored after the capture process if (captureMode == CaptureMode.GAMEVIEW_RESIZING) { GameViewController.SaveCurrentGameViewSize(); #if !UNITY_EDITOR && UNITY_STANDALONE_WIN yield return(null); yield return(new WaitForEndOfFrame()); #endif } // Capture all resolutions foreach (ScreenshotResolution resolution in resolutions) { if (!resolution.IsValid()) { continue; } // Delegate call onResolutionUpdateStartDelegate(resolution); if (colorFormat == ColorFormat.RGBA && recomputeAlphaMask) { yield return(StartCoroutine(CaptureAlphaMaskCoroutine(resolution, captureMode, antiAliasing, colorFormat))); } else { yield return(StartCoroutine(CaptureResolutionTextureCoroutine(resolution, captureMode, antiAliasing, colorFormat))); } // Delegate call onResolutionUpdateEndDelegate(resolution); #if UNITY_EDITOR // Dirty hack: we force a gameview repaint, to prevent the coroutine to stay locked. if (!Application.isPlaying) { GameViewUtils.GetGameView().Repaint(); } #endif // if (captureMode == CaptureMode.RENDER_TO_TEXTURE && captureGameUI) { // RestoreCanvasRenderMode (); // } } // Restore screen config if (restore && captureMode == CaptureMode.GAMEVIEW_RESIZING) { GameViewController.RestoreGameViewSize(); } #if (UNITY_EDITOR && !UNITY_5_4_OR_NEWER) // Call restore layout for old unity versions if (restore && captureMode == CaptureMode.GAMEVIEW_RESIZING) { m_NeedRestoreLayout = true; } #endif #if UNITY_EDITOR // Dirty hack, try to force an editor Update() to get the gameview back to normal if (!Application.isPlaying) { GameViewUtils.GetGameView().Repaint(); } #endif // Restore everything if (Application.isPlaying && stopTime) { RestoreTime(); } if (Application.isEditor || restore) { RestoreSettings(); } // End m_IsRunning = false; }
/// <summary> /// Captures the resolution texture. /// </summary> IEnumerator CaptureResolutionTextureCoroutine(ScreenshotResolution resolution, CaptureMode captureMode, int antiAliasing, ColorFormat colorFormat, bool recomputeAlphaMask) { if (!resolution.IsValid()) { yield break; } // Delegate call onResolutionUpdateStartDelegate(resolution); // Init texture m_ScreenshotTexture = GetOrCreateTexture(resolution, colorFormat, captureMode == CaptureMode.FIXED_GAMEVIEW ? true : false); if (captureMode == CaptureMode.GAMEVIEW_RESIZING) { // Force screen size change GameViewController.SetGameViewSize(m_ScreenshotTexture.width, m_ScreenshotTexture.height); yield return(new WaitForEndOfFrame()); // Force wait if (!Application.isPlaying) { // Useless texture update in editor mode when game is not running, // that takes some computational times to be sure that the UI is updated at least one time before the capture if (MultiDisplayUtils.IsMultiDisplay()) { yield return(MultiDisplayCopyRenderBufferToTextureCoroutine(m_ScreenshotTexture)); } else { CopyScreenToTexture(m_ScreenshotTexture); } } // Force screen size change, again // Particularly needed for special effects using several frame to compute their effects, like temporal anti aliasing for (int i = 0; i < m_GameViewResizingWaitingFrames; ++i) { GameViewController.SetGameViewSize(m_ScreenshotTexture.width, m_ScreenshotTexture.height); yield return(new WaitForEndOfFrame()); } // Delegate call to notify screen is resized onResolutionScreenResizedDelegate(resolution); // Capture the screen content if (MultiDisplayUtils.IsMultiDisplay()) { yield return(MultiDisplayCopyRenderBufferToTextureCoroutine(m_ScreenshotTexture)); } else { CopyScreenToTexture(m_ScreenshotTexture); } } else if (captureMode == CaptureMode.RENDER_TO_TEXTURE) { // Do not need to wait anything, just capture the cameras RenderTexture renderTexture = GetOrCreateRenderTexture(resolution, antiAliasing); RenderCamerasToTexture(m_Cameras, m_ScreenshotTexture, renderTexture); } else if (captureMode == CaptureMode.FIXED_GAMEVIEW) { // Wait for the end of rendering yield return(new WaitForEndOfFrame()); // Capture the screen content if (MultiDisplayUtils.IsMultiDisplay()) { yield return(MultiDisplayCopyRenderBufferToTextureCoroutine(m_ScreenshotTexture)); } else { CopyScreenToTexture(m_ScreenshotTexture); } } // Alpha mask if (colorFormat == ColorFormat.RGBA && recomputeAlphaMask) { // Capture the screen content yield return(StartCoroutine(RecomputeAlphaMask(resolution, m_Cameras, captureMode))); } // Delegate call onResolutionUpdateEndDelegate(resolution); }
IEnumerator RecomputeAlphaMask(ScreenshotResolution resolution, List <ScreenshotCamera> cameras, CaptureMode captureMode) { Texture2D texture = resolution.m_Texture; Texture2D mask = new Texture2D(texture.width, texture.height, TextureFormat.ARGB32, false); // Clone existing cameras List <Camera> cameraClones = new List <Camera>(); List <ScreenshotCamera> toClone = cameras; if (cameras.Count == 0) { toClone = m_SceneCameras; } foreach (ScreenshotCamera camera in toClone) { if (camera.m_Camera == null) { continue; } if (camera.m_Active == false) { continue; } Camera clone = CreateOrGetCameraClone(camera); clone.ResetAspect(); cameraClones.Add(clone); } if (captureMode == CaptureMode.RENDER_TO_TEXTURE) { // Render mask RenderTexture renderTexture = GetOrCreateRenderTexture(resolution); foreach (Camera camera in cameraClones) { camera.targetTexture = renderTexture; camera.Render(); camera.targetTexture = null; } // Copy RenderTexture tmp = RenderTexture.active; RenderTexture.active = renderTexture; mask.ReadPixels(new Rect(0, 0, mask.width, mask.height), 0, 0); mask.Apply(false); RenderTexture.active = tmp; } else { if (cameras.Count == 0) { DisableCameras(m_SceneCameras); } else { DisableCameras(cameras); } #if UNITY_EDITOR if (Application.isPlaying) { yield return(new WaitForEndOfFrame()); } else { // We need to force a gameview repaint Vector2 current = GameViewController.GetCurrentGameViewSize(); GameViewController.SetGameViewSize((int)current.x, (int)current.y); yield return(new WaitForEndOfFrame()); } #else yield return(new WaitForEndOfFrame()); #endif mask.ReadPixels(new Rect(0, 0, mask.width, mask.height), 0, 0); mask.Apply(false); if (cameras.Count == 0) { RestoreCameraSettings(m_SceneCameras); } else { RestoreCameraSettings(cameras); } } // Remove cameras foreach (Camera camera in cameraClones) { DestroyImmediate(camera.gameObject); } // Combine Color col; for (int i = 0; i < mask.width; i++) { for (int j = 0; j < mask.height; j++) { col = texture.GetPixel(i, j); col.a = mask.GetPixel(i, j).a; texture.SetPixel(i, j, col); } } }
public IEnumerator CaptureScreenshotsCoroutine(List <ScreenshotResolution> resolutions, List <ScreenshotCamera> cameras, List <ScreenshotOverlay> overlays, CaptureMode captureMode, int antiAliasing = 8, bool export = false, TextureExporter.ImageFormat imageFormat = TextureExporter.ImageFormat.PNG, int JPGQuality = 100, bool renderUI = true, bool playSound = false, ColorFormat colorFormat = ColorFormat.RGB, bool recomputeAlphaMask = false, bool stopTime = true, bool restore = true) { if (resolutions == null) { Debug.LogError("Resolution list is null."); yield break; } if (cameras == null) { Debug.LogError("Cameras list is null."); yield break; } if (overlays == null) { Debug.LogError("Overlays list is null."); yield break; } if (m_IsRunning == true) { Debug.LogError("A capture process is already running."); yield break; } if (captureMode == CaptureMode.RENDER_TO_TEXTURE && !UnityVersion.HasPro()) { Debug.LogError("RENDER_TO_TEXTURE requires Unity Pro or Unity 5.0 and later."); yield break; } #if (!UNITY_EDITOR && !UNITY_STANDALONE_WIN) if (captureMode == CaptureMode.GAMEVIEW_RESIZING) { Debug.LogError("GAMEVIEW_RESIZING capture mode is only available for Editor and Windows Standalone."); yield break; } #endif // Init m_IsRunning = true; // Stop the time so all screenshots are exactly the same if (Application.isPlaying && stopTime) { StopTime(); } // Apply settings: enable and disable the cameras and canvas ApplySettings(cameras, overlays, captureMode, renderUI); // Save the screen config to be restored after the capture process if (captureMode == CaptureMode.GAMEVIEW_RESIZING) { GameViewController.SaveCurrentGameViewSize(); #if !UNITY_EDITOR && UNITY_STANDALONE_WIN yield return(null); yield return(new WaitForEndOfFrame()); #endif } // Capture all resolutions foreach (ScreenshotResolution resolution in resolutions) { // Play the shot sound if (playSound) { PlaySound(); } // Update the texture yield return(StartCoroutine(CaptureResolutionTextureCoroutine(resolution, captureMode, antiAliasing, colorFormat, recomputeAlphaMask))); // Export to file if (export) { if (TextureExporter.ExportToFile(resolution.m_Texture, resolution.m_FileName, imageFormat, JPGQuality)) { Debug.Log("Screenshot created : " + resolution.m_FileName); onResolutionExportSuccessDelegate(resolution); } else { Debug.LogError("Failed to create : " + resolution.m_FileName); onResolutionExportFailureDelegate(resolution); } } } // Restore screen config if (restore && captureMode == CaptureMode.GAMEVIEW_RESIZING) { GameViewController.RestoreGameViewSize(); } #if (UNITY_EDITOR && !UNITY_5_4_OR_NEWER) // Call restore layout for old unity versions if (restore && captureMode == CaptureMode.GAMEVIEW_RESIZING) { m_NeedRestoreLayout = true; } #endif #if UNITY_EDITOR // Dirty hack, try to force an editor Update() to get the gameview back to normal if (captureMode == CaptureMode.FIXED_GAMEVIEW || captureMode == CaptureMode.GAMEVIEW_RESIZING) { if (!Application.isPlaying) { GameViewUtils.GetGameView().Repaint(); } } #endif // Restore everything if (Application.isPlaying && stopTime) { RestoreTime(); } if (Application.isEditor || restore) { RestoreSettings(); } // End m_IsRunning = false; }