public void OnSceneGUI() { GUI.changed = false; // Set defaultLocalRotation so that the initial local rotation will be the zero point for the rotation limit if (!Application.isPlaying) { script.defaultLocalRotation = script.transform.localRotation; } if (script.axis == Vector3.zero) { return; } // Quick Editing Tools Handles.BeginGUI(); GUILayout.BeginArea(new Rect(10, Screen.height - 180, 550, 130), "Rotation Limit Polygonal", "Window"); // Cloning values from another RotationLimitPolygonal EditorGUILayout.BeginHorizontal(); if (Inspector.Button("Clone From", "Make this rotation limit identical to another", script, GUILayout.Width(220))) { CloneLimit(); } clone = (RotationLimitPolygonal)EditorGUILayout.ObjectField("", clone, typeof(RotationLimitPolygonal), true); EditorGUILayout.EndHorizontal(); // Symmetry symmetry = (Symmetry)EditorGUILayout.EnumPopup("Symmetry", symmetry, GUILayout.Width(220)); // Flipping EditorGUILayout.BeginHorizontal(); if (Inspector.Button("Flip X", "Flip points along local X axis", script, GUILayout.Width(100))) { FlipLimit(0); } if (Inspector.Button("Flip Y", "Flip points along local Y axis", script, GUILayout.Width(100))) { FlipLimit(1); } if (Inspector.Button("Flip Z", "Flip points along local Z axis", script, GUILayout.Width(100))) { FlipLimit(2); } GUILayout.Label("Flip everything along axis"); EditorGUILayout.EndHorizontal(); // Rotating EditorGUILayout.BeginHorizontal(); if (Inspector.Button("Rotate X", "Rotate points along X axis by Degrees", script, GUILayout.Width(100))) { RotatePoints(degrees, Vector3.right); } if (Inspector.Button("Rotate Y", "Rotate points along Y axis by Degrees", script, GUILayout.Width(100))) { RotatePoints(degrees, Vector3.up); } if (Inspector.Button("Rotate Z", "Rotate points along Z axis by Degrees", script, GUILayout.Width(100))) { RotatePoints(degrees, Vector3.forward); } degrees = EditorGUILayout.FloatField("Degrees", degrees, GUILayout.Width(200)); EditorGUILayout.EndHorizontal(); // Smooth/Optimize EditorGUILayout.BeginHorizontal(); if (Inspector.Button("Smooth", "Double the points", script)) { Smooth(); } if (Inspector.Button("Optimize", "Delete every second point", script)) { Optimize(); } EditorGUILayout.EndHorizontal(); GUILayout.EndArea(); Handles.EndGUI(); // Rebuild reach cones script.BuildReachCones(); // Draw a white transparent sphere DrawRotationSphere(script.transform.position); // Draw Axis DrawArrow(script.transform.position, Direction(script.axis), colorDefault, "Axis", 0.02f); // Display limit points for (int i = 0; i < script.points.Length; i++) { Color color = GetColor(i); // Paint the point in green or red if it belongs to an invalid reach cone Handles.color = color; GUI.color = color; // Line from the center to the point and the label Handles.DrawLine(script.transform.position, script.transform.position + Direction(script.points[i].point)); Handles.Label(script.transform.position + Direction(script.points[i].point + new Vector3(-0.02f, 0, 0)), " " + i.ToString()); // Selecting points Handles.color = colorHandles; if (Inspector.DotButton(script.transform.position + Direction(script.points[i].point), script.transform.rotation, 0.02f, 0.02f)) { selectedPoint = i; } Handles.color = Color.white; GUI.color = Color.white; // Limit point GUI if (i == selectedPoint) { Handles.BeginGUI(); GUILayout.BeginArea(new Rect(Screen.width - 240, Screen.height - 180, 230, 130), "Limit Point " + i.ToString(), "Window"); if (Inspector.Button("Delete", "Delete this point", script)) { if (script.points.Length > 3) { // Using the deletePoint index here because we dont want to delete points from the array that we are iterating deletePoint = i; } else if (!Warning.logged) { script.LogWarning("Polygonal Rotation Limit should have at least 3 limit points"); } } if (Inspector.Button("Add Point", "Add a new point next to this one", script)) { addPoint = i; } // Store point for undo Vector3 oldPoint = script.points[i].point; // Manual input for the point position Inspector.AddVector3(ref script.points[i].point, "Point", script, GUILayout.Width(210)); EditorGUILayout.Space(); // Tangent weight Inspector.AddFloat(ref script.points[i].tangentWeight, "Tangent Weight", "Weight of this point's tangent. Used in smoothing.", script, -Mathf.Infinity, Mathf.Infinity, GUILayout.Width(150)); GUILayout.EndArea(); Handles.EndGUI(); // Moving Points Vector3 pointWorld = Handles.PositionHandle(script.transform.position + Direction(script.points[i].point), Quaternion.identity); Vector3 newPoint = InverseDirection(pointWorld - script.transform.position); if (newPoint != script.points[i].point) { if (!Application.isPlaying) { Undo.RecordObject(script, "Move Limit Point"); } script.points[i].point = newPoint; } // Symmetry if (symmetry != Symmetry.Off && script.points.Length > 3 && oldPoint != script.points[i].point) { RotationLimitPolygonal.LimitPoint symmetryPoint = GetClosestPoint(Symmetrize(oldPoint, symmetry)); if (symmetryPoint != script.points[i]) { symmetryPoint.point = Symmetrize(script.points[i].point, symmetry); } } } // Normalize the point script.points[i].point = script.points[i].point.normalized; } // Display smoothed polygon for (int i = 0; i < script.P.Length; i++) { Color color = GetColor(i); // Smoothed triangles are transparent Handles.color = new Color(color.r, color.g, color.b, 0.25f); Handles.DrawLine(script.transform.position, script.transform.position + Direction(script.P[i])); Handles.color = color; if (i < script.P.Length - 1) { Handles.DrawLine(script.transform.position + Direction(script.P[i]), script.transform.position + Direction(script.P[i + 1])); } else { Handles.DrawLine(script.transform.position + Direction(script.P[i]), script.transform.position + Direction(script.P[0])); } Handles.color = Color.white; } // Deleting points if (deletePoint != -1) { DeletePoint(deletePoint); selectedPoint = -1; deletePoint = -1; } // Adding points if (addPoint != -1) { AddPoint(addPoint); addPoint = -1; } if (GUI.changed) { EditorUtility.SetDirty(script); } }
public void OnSceneGUI() { GUI.changed = false; // Set defaultLocalRotation so that the initial local rotation will be the zero point for the rotation limit if (!Application.isPlaying) script.defaultLocalRotation = script.transform.localRotation; if (script.axis == Vector3.zero) return; // Quick Editing Tools Handles.BeginGUI(); GUILayout.BeginArea(new Rect(10, UnityEngine.Screen.height - 180, 550, 130), "Rotation Limit Polygonal", "Window"); // Cloning values from another RotationLimitPolygonal EditorGUILayout.BeginHorizontal(); if (Inspector.Button("Clone From", "Make this rotation limit identical to another", script, GUILayout.Width(220))) CloneLimit(); clone = (RotationLimitPolygonal)EditorGUILayout.ObjectField("", clone, typeof(RotationLimitPolygonal), true); EditorGUILayout.EndHorizontal(); // Symmetry symmetry = (Symmetry)EditorGUILayout.EnumPopup("Symmetry", symmetry, GUILayout.Width(220)); // Flipping EditorGUILayout.BeginHorizontal(); if (Inspector.Button("Flip X", "Flip points along local X axis", script, GUILayout.Width(100))) FlipLimit(0); if (Inspector.Button("Flip Y", "Flip points along local Y axis", script, GUILayout.Width(100))) FlipLimit(1); if (Inspector.Button("Flip Z", "Flip points along local Z axis", script, GUILayout.Width(100))) FlipLimit(2); GUILayout.Label("Flip everything along axis"); EditorGUILayout.EndHorizontal(); // Rotating EditorGUILayout.BeginHorizontal(); if (Inspector.Button("Rotate X", "Rotate points along X axis by Degrees", script, GUILayout.Width(100))) RotatePoints(degrees, Vector3.right); if (Inspector.Button("Rotate Y", "Rotate points along Y axis by Degrees", script, GUILayout.Width(100))) RotatePoints(degrees, Vector3.up); if (Inspector.Button("Rotate Z", "Rotate points along Z axis by Degrees", script, GUILayout.Width(100))) RotatePoints(degrees, Vector3.forward); degrees = EditorGUILayout.FloatField("Degrees", degrees, GUILayout.Width(200)); EditorGUILayout.EndHorizontal(); // Smooth/Optimize EditorGUILayout.BeginHorizontal(); if (Inspector.Button("Smooth", "Double the points", script)) Smooth(); if (Inspector.Button("Optimize", "Delete every second point", script)) Optimize(); EditorGUILayout.EndHorizontal(); GUILayout.EndArea(); Handles.EndGUI(); // Rebuild reach cones script.BuildReachCones(); // Draw a white transparent sphere DrawRotationSphere(script.transform.position); // Draw Axis DrawArrow(script.transform.position, Direction(script.axis), colorDefault, "Axis", 0.02f); // Display limit points for (int i = 0; i < script.points.Length; i++) { Color color = GetColor(i); // Paint the point in green or red if it belongs to an invalid reach cone Handles.color = color; GUI.color = color; // Line from the center to the point and the label Handles.DrawLine(script.transform.position, script.transform.position + Direction(script.points[i].point)); Handles.Label(script.transform.position + Direction(script.points[i].point + new Vector3(-0.02f, 0, 0)), " " + i.ToString()); // Selecting points Handles.color = colorHandles; if (Handles.Button(script.transform.position + Direction(script.points[i].point), script.transform.rotation, 0.02f, 0.02f, Handles.DotCap)) { selectedPoint = i; } Handles.color = Color.white; GUI.color = Color.white; // Limit point GUI if (i == selectedPoint) { Handles.BeginGUI(); GUILayout.BeginArea(new Rect(UnityEngine.Screen.width - 240, UnityEngine.Screen.height - 180, 230, 130), "Limit Point " + i.ToString(), "Window"); if (Inspector.Button("Delete", "Delete this point", script)) { if (script.points.Length > 3) { // Using the deletePoint index here because we dont want to delete points from the array that we are iterating deletePoint = i; } else if (!Warning.logged) script.LogWarning("Polygonal Rotation Limit should have at least 3 limit points"); } if (Inspector.Button("Add Point", "Add a new point next to this one", script)) { addPoint = i; } // Store point for undo Vector3 oldPoint = script.points[i].point; // Manual input for the point position Inspector.AddVector3(ref script.points[i].point, "Point", script, GUILayout.Width(210)); EditorGUILayout.Space(); // Tangent weight Inspector.AddFloat(ref script.points[i].tangentWeight, "Tangent Weight", "Weight of this point's tangent. Used in smoothing.", script, -Mathf.Infinity, Mathf.Infinity, GUILayout.Width(150)); GUILayout.EndArea(); Handles.EndGUI(); // Moving Points Vector3 pointWorld = Handles.PositionHandle(script.transform.position + Direction(script.points[i].point), Quaternion.identity); Vector3 newPoint = InverseDirection(pointWorld - script.transform.position); if (newPoint != script.points[i].point) { if (!Application.isPlaying) Undo.RecordObject(script, "Move Limit Point"); script.points[i].point = newPoint; } // Symmetry if (symmetry != Symmetry.Off && script.points.Length > 3 && oldPoint != script.points[i].point) { RotationLimitPolygonal.LimitPoint symmetryPoint = GetClosestPoint(Symmetrize(oldPoint, symmetry)); if (symmetryPoint != script.points[i]) { symmetryPoint.point = Symmetrize(script.points[i].point, symmetry); } } } // Normalize the point script.points[i].point = script.points[i].point.normalized; } // Display smoothed polygon for (int i = 0; i < script.P.Length; i++) { Color color = GetColor(i); // Smoothed triangles are transparent Handles.color = new Color(color.r, color.g, color.b, 0.25f); Handles.DrawLine(script.transform.position, script.transform.position + Direction(script.P[i])); Handles.color = color; if (i < script.P.Length - 1) Handles.DrawLine(script.transform.position + Direction(script.P[i]), script.transform.position + Direction(script.P[i + 1])); else Handles.DrawLine(script.transform.position + Direction(script.P[i]), script.transform.position + Direction(script.P[0])); Handles.color = Color.white; } // Deleting points if (deletePoint != -1) { DeletePoint(deletePoint); selectedPoint = -1; deletePoint = -1; } // Adding points if (addPoint != -1) { AddPoint(addPoint); addPoint = -1; } if (GUI.changed) EditorUtility.SetDirty(script); }