|
using System.Collections; |
|
using System.Collections.Generic; |
|
using UnityEngine; |
|
using UnityEditor; |
|
|
|
[CanEditMultipleObjects] |
|
[CustomEditor(typeof(Rectangle))] |
|
public class RectangleEditor : Editor |
|
{ |
|
/// <summary> |
|
/// Whether debug labels should be enabled globally for all |
|
/// rectangle instances |
|
/// </summary> |
|
public static bool displayDebugLabels = true; |
|
|
|
public override void OnInspectorGUI() |
|
{ |
|
//Get underlying obj |
|
Rectangle obj = (Rectangle)target; |
|
|
|
//Set debug options |
|
displayDebugLabels = EditorGUILayout.Toggle("Show global debug labels?", displayDebugLabels); |
|
|
|
EditorGUILayout.Separator(); |
|
|
|
//-------- |
|
|
|
GUIStyle boldStyle = new GUIStyle(GUI.skin.label); |
|
boldStyle.fontStyle = FontStyle.Bold; |
|
|
|
EditorGUILayout.LabelField("Debug", boldStyle); |
|
|
|
EditorGUILayout.BeginVertical(); |
|
|
|
EditorGUILayout.BeginHorizontal(); |
|
EditorGUILayout.LabelField($"Top Left = {obj.topLeft}"); |
|
EditorGUILayout.LabelField($"Top Right = {obj.topRight}"); |
|
EditorGUILayout.EndHorizontal(); |
|
|
|
EditorGUILayout.BeginHorizontal(); |
|
EditorGUILayout.LabelField($"Bottom Left = {obj.bottomLeft}"); |
|
EditorGUILayout.LabelField($"Bottom Right = {obj.bottomRight}"); |
|
EditorGUILayout.EndHorizontal(); |
|
|
|
EditorGUILayout.EndVertical(); |
|
} |
|
|
|
/// <summary> |
|
/// Draws per-vertex handles and manipulates the rectangle via calls |
|
/// to Handles |
|
/// </summary> |
|
/// <param name="rect">The rectangle</param> |
|
private void DrawVertexHandles(ref Rectangle rect) |
|
{ |
|
//The list of points from the rectangle |
|
var points = rect.points; |
|
|
|
for (int i = 0; i < points.Count; i++) |
|
{ |
|
//Run through each, set color to white |
|
Handles.color = Color.white; |
|
var point = points[i]; |
|
|
|
//Get screen-space point size |
|
float size = HandleUtility.GetHandleSize(point) * 0.1f; |
|
|
|
//Find new position and delta between this and the new point |
|
Vector3 newPos = Handles.Slider2D(point, Vector3.up, Vector3.left, Vector3.forward, size, Handles.CircleHandleCap, 0.075f); |
|
Vector3 diff = (newPos - point); |
|
|
|
//Not moved? Skip |
|
if (diff.magnitude <= 0.01f) |
|
continue; |
|
|
|
//Find points to alter x and z |
|
int changeX, changeZ; |
|
(changeX, changeZ) = rect.GetConnectedPoints(point); |
|
|
|
//Invalid indices? skip |
|
if (changeX < 0 || changeZ < 0) |
|
continue; |
|
|
|
//Find positions |
|
Vector3 changeXPos = points[changeX]; |
|
Vector3 changeZPos = points[changeZ]; |
|
|
|
//Move this point, update xz of adjacent points |
|
points[i] += diff; |
|
changeXPos.x = points[i].x; |
|
changeZPos.z = points[i].z; |
|
|
|
//Set the points |
|
points[changeX] = changeXPos; |
|
points[changeZ] = changeZPos; |
|
} |
|
|
|
//Set the points; update underlying object |
|
rect.SetPoints(points); |
|
} |
|
|
|
/// <summary> |
|
/// Draws the midpoint/centroid handle of the rectangle, which moves all points |
|
/// by a certain offset |
|
/// </summary> |
|
/// <param name="rect">The rectangle</param> |
|
private void DrawMidpointHandle(ref Rectangle rect) |
|
{ |
|
//Set to a transparent white |
|
Handles.color = new Color(1, 1, 1, 0.5f); |
|
|
|
//Find screen-space size |
|
float size = HandleUtility.GetHandleSize(rect.midpoint) * 0.15f; |
|
|
|
//Find new position and difference from old value |
|
Vector3 newPos = Handles.Slider2D(rect.midpoint, Vector3.up, Vector3.left, Vector3.forward, size, Handles.RectangleHandleCap, 0.01f); |
|
Vector3 diff = newPos - rect.midpoint; |
|
|
|
//Find all points and add the difference to all points |
|
var points = rect.points; |
|
//-- |
|
for(int i = 0; i < points.Count; i++) |
|
points[i] += diff; |
|
|
|
//Set the points, reset colour |
|
rect.SetPoints(points); |
|
Handles.color = Color.white; |
|
} |
|
|
|
/// <summary> |
|
/// Called when the scene needs rendering for this editor |
|
/// </summary> |
|
private void OnSceneGUI() |
|
{ |
|
//Find underlying object |
|
Rectangle obj = (Rectangle)target; |
|
|
|
//Gone wrong? Get out of here |
|
if (obj == null) |
|
return; |
|
|
|
//Draw the rectangular region with a transparent white |
|
Handles.color = new Color(1, 1, 1, 0.3f); |
|
Handles.DrawAAConvexPolygon(obj.points.ToArray()); |
|
|
|
//Draw outline with dotted lines |
|
Handles.color = Color.white; |
|
Handles.DrawDottedLines(obj.lineSegments.ToArray(), 2f); |
|
|
|
if (displayDebugLabels) |
|
{ |
|
//Show debug labels if needed |
|
Handles.Label(Vector3.up * 0.1f + obj.topLeft, "tL"); |
|
Handles.Label(Vector3.up * 0.1f + obj.topRight, "tR"); |
|
Handles.Label(Vector3.up * 0.1f + obj.bottomLeft, "bL"); |
|
Handles.Label(Vector3.up * 0.1f + obj.bottomRight, "bR"); |
|
} |
|
|
|
//Draw midpoint & vertex handles |
|
DrawMidpointHandle(ref obj); |
|
DrawVertexHandles(ref obj); |
|
} |
|
} |