ScreenshotManager.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. using BepInEx;
  2. using BepInEx.Common;
  3. using Illusion.Game;
  4. using System;
  5. using System.Collections;
  6. using System.Collections.Generic;
  7. using System.IO;
  8. using System.Linq;
  9. using System.Text;
  10. using UnityEngine;
  11. namespace Screencap
  12. {
  13. public class ScreenshotManager : BaseUnityPlugin
  14. {
  15. public override string Name => "Screenshot Manager";
  16. Event ScreenKeyEvent;
  17. Event CharacterKeyEvent;
  18. private string screenshotDir = Utility.CombinePaths(Utility.ExecutingDirectory, "UserData", "cap");
  19. public ScreenshotManager()
  20. {
  21. ScreenKeyEvent = Event.KeyboardEvent("f9");
  22. CharacterKeyEvent = Event.KeyboardEvent("f11");
  23. if (!Directory.Exists(screenshotDir))
  24. Directory.CreateDirectory(screenshotDir);
  25. }
  26. void LateUpdate()
  27. {
  28. if (UnityEngine.Event.current.Equals(ScreenKeyEvent))
  29. {
  30. string filename = Path.Combine(screenshotDir, $"Koikatsu-{DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss")}.png");
  31. StartCoroutine(TakeScreenshot(filename));
  32. }
  33. else if (UnityEngine.Event.current.Equals(CharacterKeyEvent))
  34. {
  35. string filename = Path.Combine(screenshotDir, $"Koikatsu Char-{DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss")}.png");
  36. TakeCharScreenshot(filename);
  37. }
  38. }
  39. IEnumerator TakeScreenshot(string filename)
  40. {
  41. Application.CaptureScreenshot(filename);
  42. Illusion.Game.Utils.Sound.Play(SystemSE.photo);
  43. while (!File.Exists(filename))
  44. yield return new WaitForSeconds(0.01f);
  45. BepInLogger.Log($"Screenshot saved to {filename}", true);
  46. }
  47. void TakeCharScreenshot(string filename)
  48. {
  49. Camera.main.backgroundColor = Color.clear;
  50. var tex = RenderCamera(Camera.main);
  51. File.WriteAllBytes(filename, tex.EncodeToPNG());
  52. Destroy(tex);
  53. Illusion.Game.Utils.Sound.Play(SystemSE.photo);
  54. BepInLogger.Log($"Character screenshot saved to {filename}", true);
  55. }
  56. Texture2D RenderCamera(Camera cam)
  57. {
  58. var go = new GameObject();
  59. Camera renderCam = go.AddComponent<Camera>();
  60. renderCam.CopyFrom(Camera.main);
  61. CopyComponents(Camera.main.gameObject, renderCam.gameObject);
  62. renderCam.targetTexture = new RenderTexture(2048, 2048, 32); //((int)cam.pixelRect.width, (int)cam.pixelRect.height, 32);
  63. renderCam.aspect = renderCam.targetTexture.width / (float)renderCam.targetTexture.height;
  64. RenderTexture currentRT = RenderTexture.active;
  65. RenderTexture.active = renderCam.targetTexture;
  66. renderCam.Render();
  67. Texture2D image = new Texture2D(renderCam.targetTexture.width, renderCam.targetTexture.height);
  68. image.ReadPixels(new Rect(0, 0, renderCam.targetTexture.width, renderCam.targetTexture.height), 0, 0);
  69. image.Apply();
  70. RenderTexture.active = currentRT;
  71. Destroy(renderCam.targetTexture);
  72. Destroy(renderCam);
  73. return image;
  74. }
  75. void CopyComponents(GameObject original, GameObject target)
  76. {
  77. foreach (Component component in original.GetComponents<Component>())
  78. {
  79. var newComponent = CopyComponent(component, target);
  80. if (component is MonoBehaviour)
  81. {
  82. var behavior = (MonoBehaviour)component;
  83. (newComponent as MonoBehaviour).enabled = behavior.enabled;
  84. }
  85. }
  86. }
  87. //https://answers.unity.com/questions/458207/copy-a-component-at-runtime.html
  88. Component CopyComponent(Component original, GameObject destination)
  89. {
  90. System.Type type = original.GetType();
  91. Component copy = destination.AddComponent(type);
  92. // Copied fields can be restricted with BindingFlags
  93. System.Reflection.FieldInfo[] fields = type.GetFields();
  94. foreach (System.Reflection.FieldInfo field in fields)
  95. {
  96. field.SetValue(copy, field.GetValue(original));
  97. }
  98. return copy;
  99. }
  100. }
  101. }