using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; // Scene视图中的自定义handles public static class EditorHandlesHelper { static int s_ValueScaleHandleHash; // limit value 数据 static float s_StartScale; static float s_ValueDrag; static float s_ScaleDrawLength; // style static GUIStyle s_StyleBlackLabel; static GUIStyle s_StyleWhiteLabel; static Dictionary s_StyleLabels; static EditorHandlesHelper() { s_ValueScaleHandleHash = "ValueScaleHandleHash".GetHashCode(); SetupStyles(); } static void SetupStyles() { s_StyleBlackLabel = new GUIStyle(); s_StyleBlackLabel.normal.textColor = Color.black; s_StyleWhiteLabel = new GUIStyle(); s_StyleWhiteLabel.normal.textColor = Color.white; s_StyleLabels = new Dictionary(); } #region 单一handle // 箭头 public static void Arrow(Vector3 position, Vector3 direction, float length = 1f, float arrowSize = 0.1f, bool dotted = false) { direction = direction.normalized; if(!dotted) Handles.DrawLine(position, position + direction * length); else Handles.DrawDottedLine(position, position + direction * length,1f); Handles.ConeHandleCap(0, position + direction * length, Quaternion.LookRotation(direction, Vector3.up), arrowSize, EventType.Repaint); } // 控制数值的箭头 public static float ScaleValue(float value, Vector3 position, Vector3 direction, float length, Handles.CapFunction capFunc, Quaternion capRot, float size, float snap = 0) { Handles.DrawLine(position, position + direction * length); value = ScaleValue(value, position + direction, capRot, size, capFunc, snap); return value; } // 控制数值的handle public static float ScaleValue(float value, Vector3 position, Quaternion rotation, float size, Handles.CapFunction capFunc, float snap) { int controlID = GUIUtility.GetControlID(s_ValueScaleHandleHash, FocusType.Keyboard); int id = controlID; Event current = Event.current; switch (current.GetTypeForControl(id)) { case EventType.MouseDown: if ((HandleUtility.nearestControl == id && current.button == 0) || (GUIUtility.keyboardControl == id && current.button == 2)) { GUIUtility.keyboardControl = id; GUIUtility.hotControl = id; s_StartScale = value; s_ValueDrag = 0f; current.Use(); EditorGUIUtility.SetWantsMouseJumping(1); } break; case EventType.MouseUp: if (GUIUtility.hotControl == id && (current.button == 0 || current.button == 2)) { GUIUtility.hotControl = 0; s_ScaleDrawLength = 1f; current.Use(); EditorGUIUtility.SetWantsMouseJumping(0); } break; case EventType.MouseDrag: if (GUIUtility.hotControl == id) { s_ValueDrag += HandleUtility.niceMouseDelta * 0.01f; value = (Handles.SnapValue(s_ValueDrag, snap) + 1f) * s_StartScale; s_ScaleDrawLength = value / s_StartScale; GUI.changed = true; current.Use(); } break; case EventType.KeyDown: if (GUIUtility.hotControl == id && current.keyCode == KeyCode.Escape) { value = s_StartScale; s_ScaleDrawLength = 1f; GUIUtility.hotControl = 0; GUI.changed = true; current.Use(); } break; case EventType.Repaint: { Color color = Color.white; if (id == GUIUtility.keyboardControl) { color = Handles.color; Handles.color = Handles.selectedColor; } capFunc(id, position, rotation, size * 0.15f, EventType.Repaint); if (id == GUIUtility.keyboardControl) { Handles.color = color; } break; } case EventType.Layout: HandleUtility.AddControl(id, HandleUtility.DistanceToCircle(position, size * 0.15f)); break; } return value; } // 带背景的label public static void Label(Vector3 position, string label, Color textColor) { GUIStyle textStyle = TryGetLabelStyleOrCreate(textColor); Handles.Label(position, label, textStyle); } public static void WireCube(Vector3 position, Vector3 size, Color col) { Color c = Handles.color; Handles.color = col; Handles.DrawWireCube(position, size); Handles.color = c; } #endregion #region 复合handle #endregion #region 内部方法 static GUIStyle TryGetLabelStyleOrCreate(Color color) { GUIStyle style; if (!s_StyleLabels.TryGetValue(color.GetHashCode(), out style)) { style = new GUIStyle(); style.normal.textColor = color; s_StyleLabels.Add(color.GetHashCode(), style); } return style; } #endregion }