using System; using System.Collections; using System.IO; using uGIF; using UnityEngine; using UnityEngine.UI; using Image = uGIF.Image; public class Screenshot : MonoBehaviour { public static Screenshot Instance; bool recording = false; public Button RecordButton; public TMPro.TMP_InputField ScreenshotWidth, ScreenshotHeight, GifWidth, GifHeight; public TMPro.TMP_Dropdown CaptureAntialiasing; public Toggle CaptureTransparent; private void Awake() { Instance = this; } public void TakeScreenshot() { var camera = ModelViewerMain.GetInstance().GetCamera().Cam; int width = string.IsNullOrEmpty(ScreenshotWidth.text)? 0 : int.Parse(ScreenshotWidth.text); int height = string.IsNullOrEmpty(ScreenshotHeight.text) ? 0 : int.Parse(ScreenshotHeight.text); width = width == 0 ? Screen.width : width; height = height == 0 ? Screen.height : height; var image = GrabFrame(camera, width, height, CaptureTransparent.isOn, GetAntialiasing()); string fileName = Application.dataPath + "/../Screenshots/" + string.Format("UniViewer_{0}", DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss-fff")); byte[] pngShot = ImageConversion.EncodeToPNG(image); Directory.CreateDirectory(Application.dataPath + "/../Screenshots"); var fullpath = Path.GetFullPath($"{fileName}.png"); File.WriteAllBytes(fullpath, pngShot); Error.Log($"Screenshot saved: {fullpath}", Color.green); Destroy(image); } public void BeginRecordGif() { if (recording || ModelViewerMain.GetInstance().SelectedObject == null) { Error.Log(Color.yellow, "Target not found"); return; } recording = true; RecordButton.interactable = false; int width = string.IsNullOrEmpty(GifWidth.text) ? 0 : int.Parse(GifWidth.text); int height = string.IsNullOrEmpty(GifHeight.text) ? 0 : int.Parse(GifHeight.text); ModelViewerMain.GetInstance().StartCoroutine(RecordGif(width, height, CaptureTransparent.isOn, GetAntialiasing())); //(int)UmaViewerUI.Instance.GifQuality.value)); } private IEnumerator RecordGif(int width, int height, bool transparent, int antialiasing) { var camera = ModelViewerMain.GetInstance().GetCamera().Cam; var currentCharacter = ModelViewerMain.GetInstance().SelectedObject; if (currentCharacter as IAnimated == null) yield break; var animator = (currentCharacter as IAnimated).GetAnimator(); if (animator == null) yield break; var previousSpeed = animator.speed; int frame = 0; var animeClip = (animator.runtimeAnimatorController as AnimatorOverrideController)["Anim"]; var clipFrameCount = Mathf.RoundToInt(animeClip.length * animeClip.frameRate); ModelViewerMain.GetInstance().StartCoroutine(CaptureToGIFCustom.Instance.Encode(animeClip.frameRate, 10)); animator.speed = 0; while (frame < clipFrameCount) { animator.Play("Anim", 0, (float)frame / clipFrameCount); yield return new WaitForEndOfFrame(); var tex = GrabFrame(camera, width, height, transparent, antialiasing, transparent); CaptureToGIFCustom.Instance.Frames.Add(new Image(tex)); Destroy(tex); frame++; } recording = false; CaptureToGIFCustom.Instance.stop = true; RecordButton.interactable = true; animator.speed = previousSpeed; } public static Texture2D GrabFrame(Camera cam, int width, int height, bool transparent = true, int antialiasing = 2, bool gifBackground = false) { var dimensions = GetResolution(width, height); width = dimensions.x; height = dimensions.y; int oldMask = cam.cullingMask; var oldClearFlags = cam.clearFlags; Color oldBG = cam.backgroundColor; cam.cullingMask = ~LayerMask.GetMask("UI"); if (gifBackground || transparent) { cam.clearFlags = CameraClearFlags.SolidColor; cam.backgroundColor = new Color32(0, 0, 0, 0); } var tex_color = new Texture2D(width, height, TextureFormat.ARGB32, false); var render_texture = RenderTexture.GetTemporary(width, height, 24, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default, antialiasing); var grab_area = new Rect(0, 0, width, height); RenderTexture.active = render_texture; cam.targetTexture = render_texture; cam.Render(); tex_color.ReadPixels(grab_area, 0, 0); tex_color.Apply(); cam.clearFlags = oldClearFlags; cam.cullingMask = oldMask; cam.backgroundColor = oldBG; cam.targetTexture = null; RenderTexture.active = null; RenderTexture.ReleaseTemporary(render_texture); return tex_color; } public static Vector2Int GetResolution(int width, int height) { if (width == 0 && height == 0) { width = Screen.width; height = Screen.height; } else if (width == 0) { float ratio = (float)Screen.width / (float)Screen.height; width = Mathf.RoundToInt((float)height * ratio); } else if (height == 0) { float ratio = (float)Screen.height / (float)Screen.width; height = Mathf.RoundToInt((float)width * ratio); } return new Vector2Int(width, height); } private int GetAntialiasing() { return int.Parse(CaptureAntialiasing.options[CaptureAntialiasing.value].text); } }