using System.IO; using UnityEngine; #if UNITY_EDITOR using UnityEditor; #endif namespace gay.lilyy.PlaneCam { [AddComponentMenu("LillithRosePup/Camera To Image")] [RequireComponent(typeof(Camera))] public class PlaneCam : MonoBehaviour, VRC.SDKBase.IEditorOnly { private const string DefaultOutputImagePath = "Output.png"; public string outputImagePath = DefaultOutputImagePath; [Tooltip("If set to a value greater than 0, the image will be scaled so its longest side matches this value while maintaining aspect ratio")] public int longestSide = 1024; } #if UNITY_EDITOR [CustomEditor(typeof(PlaneCam))] public class PlaneCamEditor : Editor { public override void OnInspectorGUI() { base.OnInspectorGUI(); if (GUILayout.Button("Capture Image")) { var camera = target as PlaneCam; } } private void CaptureImage(PlaneCam camDef) { var camera = camDef.GetComponent(); float aspectRatio = camera.aspect; int cameraWidth = camera.pixelWidth; int cameraHeight = camera.pixelHeight; int outputWidth, outputHeight; if (aspectRatio > 1f) { outputHeight = cameraHeight; outputWidth = Mathf.RoundToInt(cameraHeight * aspectRatio); if (outputWidth > cameraWidth) { outputWidth = cameraWidth; outputHeight = Mathf.RoundToInt(cameraWidth / aspectRatio); } } else { outputWidth = cameraWidth; outputHeight = Mathf.RoundToInt(cameraWidth / aspectRatio); if (outputHeight > cameraHeight) { outputHeight = cameraHeight; outputWidth = Mathf.RoundToInt(cameraHeight * aspectRatio); } } // Scale to longest side if specified if (camDef.longestSide > 0) { int currentLongestSide = Mathf.Max(outputWidth, outputHeight); if (currentLongestSide != camDef.longestSide) { float scale = (float)camDef.longestSide / currentLongestSide; outputWidth = Mathf.RoundToInt(outputWidth * scale); outputHeight = Mathf.RoundToInt(outputHeight * scale); } } var renderTexture = new RenderTexture(outputWidth, outputHeight, 24); camera.targetTexture = renderTexture; camera.Render(); var screenshot = new Texture2D(outputWidth, outputHeight, TextureFormat.ARGB32, false); RenderTexture.active = renderTexture; screenshot.ReadPixels(new Rect(0, 0, outputWidth, outputHeight), 0, 0); screenshot.Apply(); RenderTexture.active = null; camera.targetTexture = null; renderTexture.Release(); var bytes = screenshot.EncodeToPNG(); File.WriteAllBytes("Assets/" + camDef.outputImagePath, bytes); AssetDatabase.Refresh(); Debug.Log($"Image captured and saved to: Assets/{camDef.outputImagePath}. Aspect Ratio: {aspectRatio:F2} ({outputWidth}x{outputHeight})"); } } #endif }