using UnityEditor; using UnityEngine; namespace Core.Camera.Editor { [CustomEditor(typeof(CameraRig))] public class CameraRigEditor : UnityEditor.Editor { CameraRig m_CameraRig; Rect m_MapSize; SerializedProperty m_SerializedPropertyMapSize; /// /// Adds a label below the default inspector GUI /// public override void OnInspectorGUI() { base.OnInspectorGUI(); EditorGUILayout.Space(); EditorGUILayout.LabelField("Resize the map rect size using the handles in scene.", EditorStyles.boldLabel); } /// /// Draws and handles input for manipulating the map size /// void OnSceneGUI() { float y = m_CameraRig.floorY; Plane floor = new Plane(Vector3.up, y); float middleX = (m_MapSize.xMax + m_MapSize.xMin) * 0.5f; float middleY = (m_MapSize.yMax + m_MapSize.yMin) * 0.5f; Vector3 bottomPosition = new Vector3(middleX, y, m_MapSize.yMin), topPosition = new Vector3(middleX, y, m_MapSize.yMax), leftPosition = new Vector3(m_MapSize.xMin, y, middleY), rightPosition = new Vector3(m_MapSize.xMax, y, middleY); // Draw handles to resize map rect float size = HandleUtility.GetHandleSize(m_CameraRig.transform.position) * 0.125f; Vector3 snap = Vector3.one * 0.5f; Vector3 bottom = Handles.FreeMoveHandle(bottomPosition, Quaternion.LookRotation(Vector3.up), size, snap, Handles.RectangleHandleCap); Vector3 top = Handles.FreeMoveHandle(topPosition, Quaternion.LookRotation(Vector3.up), size, snap, Handles.RectangleHandleCap); Vector3 left = Handles.FreeMoveHandle(leftPosition, Quaternion.LookRotation(Vector3.up), size, snap, Handles.RectangleHandleCap); Vector3 right = Handles.FreeMoveHandle(rightPosition, Quaternion.LookRotation(Vector3.up), size, snap, Handles.RectangleHandleCap); ReprojectOntoFloor(ref bottom, floor); ReprojectOntoFloor(ref top, floor); ReprojectOntoFloor(ref left, floor); ReprojectOntoFloor(ref right, floor); // Draw a box to represent the map rect Vector3 topLeft = new Vector3(m_MapSize.x, y, m_MapSize.y), topRight = topLeft + new Vector3(m_MapSize.width, 0, 0), bottomLeft = topLeft + new Vector3(0, 0, m_MapSize.height), bottomRight = bottomLeft + new Vector3(m_MapSize.width, 0, 0); Handles.DrawLine(topLeft, topRight); Handles.DrawLine(topRight, bottomRight); Handles.DrawLine(bottomRight, bottomLeft); Handles.DrawLine(bottomLeft, topLeft); m_MapSize.xMin = left.x; m_MapSize.xMax = right.x; m_MapSize.yMin = bottom.z; m_MapSize.yMax = top.z; if (m_SerializedPropertyMapSize.rectValue != m_MapSize) { m_SerializedPropertyMapSize.rectValue = m_MapSize; serializedObject.ApplyModifiedProperties(); } } /// /// Reproject moved positions back onto floor plane (they move in 3D space so it can feel sluggish /// if we take their new position and clamp it back down to plane y /// static void ReprojectOntoFloor(ref Vector3 worldPoint, Plane floor) { UnityEngine.Camera sceneCam = UnityEngine.Camera.current; if (sceneCam != null) { float dist; Ray camray = sceneCam.ScreenPointToRay(sceneCam.WorldToScreenPoint(worldPoint)); if (floor.Raycast(camray, out dist)) { worldPoint = camray.GetPoint(dist); } } } /// /// Gets the serializedObject for editing /// void OnEnable() { m_CameraRig = target as CameraRig; m_SerializedPropertyMapSize = serializedObject.FindProperty("mapSize"); m_MapSize = m_SerializedPropertyMapSize.rectValue; } } }