// // =============================================================================== // // MeasureTool - Smart Scene Measurement & Analysis // // // // Creator: Scove // // Last Updated: 2024-05-08 // // Version: 3.0 // // // // Purpose: // // A professional measurement tool that visualizes distances between objects // // in the Scene View. Supports single distance, chain distance, and axis breakdown. // // // // Key Features: // // 1. Two-Point & Chain Mode: Select 2 or more objects to measure. // // 2. Axis Breakdown: Shows Delta X, Y, Z with Unity-standard colors. // // 3. Scene Overlay: On-screen toggle and settings directly in Scene View. // // 4. Readable UI: High-contrast labels with background for any lighting condition. // // // // How to Use: // // 1. Place in an 'Editor' folder. // // 2. Select 2 or more GameObjects in the Hierarchy. // // 3. Use the "MEASURE" overlay in the Scene View to toggle axis details. // // =============================================================================== // // #if UNITY_EDITOR // using UnityEditor; // using UnityEngine; // using System.Collections.Generic; // // namespace Editor // { // [InitializeOnLoad] // public class MeasureTool // { // // Settings (Persisted via EditorPrefs) // private static bool IsEnabled = true; // private static bool ShowAxisBreakdown = true; // private static bool ShowTotalDistance = true; // // static MeasureTool() // { // IsEnabled = EditorPrefs.GetBool("MeasureTool_Enabled", true); // ShowAxisBreakdown = EditorPrefs.GetBool("MeasureTool_Axis", true); // // SceneView.duringSceneGui += OnSceneGUI; // } // // private static void OnSceneGUI(SceneView view) // { // DrawOverlay(view); // // if (!IsEnabled || Selection.transforms.Length < 2) return; // // Transform[] selected = Selection.transforms; // // // Draw measurement for each pair in the selection // for (int i = 0; i < selected.Length - 1; i++) // { // DrawDistance(selected[i].position, selected[i + 1].position); // } // } // // private static void DrawDistance(Vector3 p1, Vector3 p2) // { // float distance = Vector3.Distance(p1, p2); // Vector3 midPoint = (p1 + p2) * 0.5f; // // // 1. Draw the Main Dotted Line // Handles.color = Color.cyan; // Handles.DrawDottedLine(p1, p2, 4f); // // // Draw small spheres at start/end points for clarity // Handles.SphereHandleCap(0, p1, Quaternion.identity, 0.1f, EventType.Repaint); // Handles.SphereHandleCap(0, p2, Quaternion.identity, 0.1f, EventType.Repaint); // // // 2. Draw Main Label (Total Distance) // if (ShowTotalDistance) // { // GUIStyle labelStyle = GetLabelStyle(Color.white, new Color(0, 0, 0, 0.6f)); // string labelText = $"Dist: {distance:F2}m"; // Handles.Label(midPoint + (Vector3.up * 0.1f), labelText, labelStyle); // } // // // 3. Draw Axis Breakdown (X, Y, Z Delta) // if (ShowAxisBreakdown) // { // Vector3 delta = new Vector3(Mathf.Abs(p1.x - p2.x), Mathf.Abs(p1.y - p2.y), Mathf.Abs(p1.z - p2.z)); // // // We only show axis delta if it's significant (> 0.01) // string axisText = ""; // if (delta.x > 0.01f) axisText += $"X: {delta.x:F2} "; // if (delta.y > 0.01f) axisText += $"Y: {delta.y:F2} "; // if (delta.z > 0.01f) axisText += $"Z: {delta.z:F2}"; // // if (!string.IsNullOrEmpty(axisText)) // { // GUIStyle axisStyle = GetLabelStyle(Color.white, new Color(0.1f, 0.1f, 0.1f, 0.8f)); // axisStyle.richText = true; // axisStyle.fontSize = 11; // Handles.Label(midPoint - (Vector3.up * 0.3f), axisText, axisStyle); // } // } // } // // private static void DrawOverlay(SceneView view) // { // Handles.BeginGUI(); // // // Positioning the overlay in the bottom right // float width = 140; // float height = 90; // Rect rect = new Rect(view.position.width - width - 10, view.position.height - height - 30, width, height); // // GUILayout.BeginArea(rect, "MEASURE TOOL", GUI.skin.window); // // EditorGUI.BeginChangeCheck(); // // IsEnabled = GUILayout.Toggle(IsEnabled, " Enable Tool"); // ShowTotalDistance = GUILayout.Toggle(ShowTotalDistance, " Show Total"); // ShowAxisBreakdown = GUILayout.Toggle(ShowAxisBreakdown, " Axis Breakdown"); // // if (EditorGUI.EndChangeCheck()) // { // EditorPrefs.SetBool("MeasureTool_Enabled", IsEnabled); // EditorPrefs.SetBool("MeasureTool_Axis", ShowAxisBreakdown); // SceneView.RepaintAll(); // } // // GUILayout.EndArea(); // Handles.EndGUI(); // } // // private static GUIStyle GetLabelStyle(Color textColor, Color bgColor) // { // GUIStyle style = new GUIStyle(); // style.normal.textColor = textColor; // style.fontSize = 13; // style.fontStyle = FontStyle.Bold; // style.alignment = TextAnchor.MiddleCenter; // style.padding = new RectOffset(4, 4, 2, 2); // // // Create a background texture dynamically // Texture2D tex = new Texture2D(1, 1); // tex.SetPixel(0, 0, bgColor); // tex.Apply(); // style.normal.background = tex; // // return style; // } // } // } // #endif