using UnityEngine; using UnityEditor; using gay.lilyy.PlaneCam; namespace gay.lilyy.PlaneCam.Editor { [InitializeOnLoad] public class PlaneCamEditor { static PlaneCamEditor() { EditorApplication.update += UpdatePlaneCams; } static void UpdatePlaneCams() { PlaneCam[] planeCams = Object.FindObjectsOfType(true); foreach (PlaneCam planeCam in planeCams) { if (planeCam == null || planeCam.target == null) continue; Camera cam = planeCam.GetComponent(); if (cam == null) continue; // Get the bounds of the target plane Bounds bounds = GetBounds(planeCam.target); if (bounds.size.magnitude < 0.001f) continue; // Get plane normal and center Vector3 planeNormal = GetPlaneNormal(planeCam.target, planeCam.direction); Vector3 planeCenter = bounds.center; // Calculate the plane's dimensions in its local space // Project bounds size onto the plane's local axes Transform planeTransform = planeCam.target.transform; Vector3 localSize = bounds.size; // Find the two dimensions that define the plane (ignore the smallest dimension) // This assumes the plane is flat, so one dimension should be very small float minDim = Mathf.Min(localSize.x, localSize.y, localSize.z); float maxDim = Mathf.Max(localSize.x, localSize.y, localSize.z); float midDim = localSize.x + localSize.y + localSize.z - minDim - maxDim; // Use the larger of the two plane dimensions to ensure it fills the square viewport float planeSize = Mathf.Max(maxDim, midDim); // Set aspect ratio to 1:1 for square viewport cam.aspect = 1.0f; // Calculate distance and position if (cam.orthographic) { cam.orthographicSize = planeSize * 0.5f; // Position camera perpendicular to the plane cam.transform.position = planeCenter - planeNormal * 10f; // Distance doesn't matter for orthographic cam.transform.LookAt(planeCenter, planeTransform.up); } else { // For perspective camera, calculate distance based on FOV // distance = (size/2) / tan(FOV/2) float halfFOV = cam.fieldOfView * 0.5f * Mathf.Deg2Rad; float distance = (planeSize * 0.5f) / Mathf.Tan(halfFOV); // Position camera perpendicular to the plane, looking at center cam.transform.position = planeCenter - planeNormal * distance; cam.transform.LookAt(planeCenter, planeTransform.up); } } } static Bounds GetBounds(GameObject target) { Renderer renderer = target.GetComponent(); if (renderer != null) { return renderer.bounds; } // If no renderer, try to get bounds from collider Collider collider = target.GetComponent(); if (collider != null) { return collider.bounds; } // Fallback: use transform scale return new Bounds(target.transform.position, target.transform.lossyScale); } static Vector3 GetPlaneNormal(GameObject target, PlaneDirection direction) { Transform t = target.transform; // Use the specified direction setting switch (direction) { case PlaneDirection.XPositive: return t.right; case PlaneDirection.XNegative: return -t.right; case PlaneDirection.YPositive: return t.up; case PlaneDirection.YNegative: return -t.up; case PlaneDirection.ZPositive: return t.forward; case PlaneDirection.ZNegative: return -t.forward; default: return t.forward; } } } }