ScreenshotManager.cs 4.1 KB

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