/// <summary> /// Отрисовывает перемещаемую "точку" в редиме редактировния /// </summary> /// <param name="position">Предыдущее положение точки</param> /// <param name="handleSize">Размер видимой перемещаемой точки</param> /// <param name="capFunc">Функция отрисовки перемещаемой точки</param> /// <param name="colorSelected">Цвето точки при выделении</param> /// <param name="result">Текущее событие</param> /// <returns>Возвращает новую позицию точки</returns> public static Vector3 DragHandle(Vector3 position, float handleSize, Handles.DrawCapFunction capFunc, Color colorSelected, out DragHandleResult result) { int id = GUIUtility.GetControlID(s_DragHandleHash, FocusType.Passive); lastDragHandleID = id; Vector3 screenPosition = Handles.matrix.MultiplyPoint(position); Matrix4x4 cachedMatrix = Handles.matrix; result = DragHandleResult.None; switch (Event.current.GetTypeForControl(id)) { case EventType.MouseDown: if (HandleUtility.nearestControl == id && (Event.current.button == 0 || Event.current.button == 1)) { GUIUtility.hotControl = id; s_DragHandleMouseCurrent = s_DragHandleMouseStart = Event.current.mousePosition; s_DragHandleWorldStart = position; s_DragHandleHasMoved = false; Event.current.Use(); EditorGUIUtility.SetWantsMouseJumping(1); if (Event.current.button == 0) result = DragHandleResult.LeftMouseButtonPress; else if (Event.current.button == 1) result = DragHandleResult.RightMouseButtonPress; } break; case EventType.MouseUp: if (GUIUtility.hotControl == id && (Event.current.button == 0 || Event.current.button == 1)) { GUIUtility.hotControl = 0; Event.current.Use(); EditorGUIUtility.SetWantsMouseJumping(0); if (Event.current.button == 0) result = DragHandleResult.LeftMouseButtonRelease; else if (Event.current.button == 1) result = DragHandleResult.RightMouseButtonRelease; if (Event.current.mousePosition == s_DragHandleMouseStart) { bool doubleClick = (s_DragHandleClickID == id) && (Time.realtimeSinceStartup - s_DragHandleClickTime < s_DragHandleDoubleClickInterval); s_DragHandleClickID = id; s_DragHandleClickTime = Time.realtimeSinceStartup; if (Event.current.button == 0) result = doubleClick ? DragHandleResult.LeftMouseButtonDoubleClick : DragHandleResult.LeftMouseButtonClick; else if (Event.current.button == 1) result = doubleClick ? DragHandleResult.RightMouseButtonDoubleClick : DragHandleResult.RightMouseButtonClick; } } break; case EventType.MouseDrag: if (GUIUtility.hotControl == id) { s_DragHandleMouseCurrent += new Vector2(Event.current.delta.x, -Event.current.delta.y); Vector3 position2 = Camera.current.WorldToScreenPoint(Handles.matrix.MultiplyPoint(s_DragHandleWorldStart)) + (Vector3)(s_DragHandleMouseCurrent - s_DragHandleMouseStart); position = Handles.matrix.inverse.MultiplyPoint(Camera.current.ScreenToWorldPoint(position2)); if (Camera.current.transform.forward == Vector3.forward || Camera.current.transform.forward == -Vector3.forward) position.z = s_DragHandleWorldStart.z; if (Camera.current.transform.forward == Vector3.up || Camera.current.transform.forward == -Vector3.up) position.y = s_DragHandleWorldStart.y; if (Camera.current.transform.forward == Vector3.right || Camera.current.transform.forward == -Vector3.right) position.x = s_DragHandleWorldStart.x; if (Event.current.button == 0) result = DragHandleResult.LeftMouseButtonDrag; else if (Event.current.button == 1) result = DragHandleResult.RightMouseButtonDrag; s_DragHandleHasMoved = true; GUI.changed = true; Event.current.Use(); } break; case EventType.Repaint: Color currentColour = Handles.color; if (id == GUIUtility.hotControl && s_DragHandleHasMoved) Handles.color = colorSelected; Handles.matrix = Matrix4x4.identity; capFunc(id, screenPosition, Quaternion.identity, handleSize); Handles.matrix = cachedMatrix; Handles.color = currentColour; break; case EventType.Layout: Handles.matrix = Matrix4x4.identity; HandleUtility.AddControl(id, HandleUtility.DistanceToCircle(screenPosition, handleSize)); Handles.matrix = cachedMatrix; break; } return position; }
public static Vector3 DragHandle(Vector3 position, float handleSize, Handles.DrawCapFunction capFunc, Color colorSelected, out DragHandleResult result) { int id = GUIUtility.GetControlID(s_DragHandleHash, FocusType.Passive); lastDragHandleID = id; Vector3 screenPosition = Handles.matrix.MultiplyPoint(position); Matrix4x4 cachedMatrix = Handles.matrix; result = DragHandleResult.none; switch (Event.current.GetTypeForControl(id)) { case EventType.MouseDown: if (HandleUtility.nearestControl == id && (Event.current.button == 0 || Event.current.button == 1)) { GUIUtility.hotControl = id; s_DragHandleMouseCurrent = s_DragHandleMouseStart = Event.current.mousePosition; s_DragHandleWorldStart = position; s_DragHandleHasMoved = false; Event.current.Use(); EditorGUIUtility.SetWantsMouseJumping(1); if (Event.current.button == 0) { result = DragHandleResult.LMBPress; } else if (Event.current.button == 1) { result = DragHandleResult.RMBPress; } } break; case EventType.MouseUp: if (GUIUtility.hotControl == id && (Event.current.button == 0 || Event.current.button == 1)) { // GUIUtility.hotControl = 0; Event.current.Use(); EditorGUIUtility.SetWantsMouseJumping(0); if (Event.current.button == 0) { result = DragHandleResult.LMBRelease; } else if (Event.current.button == 1) { result = DragHandleResult.RMBRelease; } if (Event.current.mousePosition == s_DragHandleMouseStart) { bool doubleClick = (s_DragHandleClickID == id) && (Time.realtimeSinceStartup - s_DragHandleClickTime < s_DragHandleDoubleClickInterval); s_DragHandleClickID = id; s_DragHandleClickTime = Time.realtimeSinceStartup; if (Event.current.button == 0) { result = doubleClick ? DragHandleResult.LMBDoubleClick : DragHandleResult.LMBClick; } else if (Event.current.button == 1) { result = doubleClick ? DragHandleResult.RMBDoubleClick : DragHandleResult.RMBClick; } } } break; case EventType.MouseDrag: if (GUIUtility.hotControl == id) { s_DragHandleMouseCurrent += new Vector2(Event.current.delta.x, -Event.current.delta.y); Vector3 position2 = Camera.current.WorldToScreenPoint(Handles.matrix.MultiplyPoint(s_DragHandleWorldStart)) + (Vector3)(s_DragHandleMouseCurrent - s_DragHandleMouseStart); position = Handles.matrix.inverse.MultiplyPoint(Camera.current.ScreenToWorldPoint(position2)); if (Camera.current.transform.forward == Vector3.forward || Camera.current.transform.forward == -Vector3.forward) { position.z = s_DragHandleWorldStart.z; } if (Camera.current.transform.forward == Vector3.up || Camera.current.transform.forward == -Vector3.up) { position.y = s_DragHandleWorldStart.y; } if (Camera.current.transform.forward == Vector3.right || Camera.current.transform.forward == -Vector3.right) { position.x = s_DragHandleWorldStart.x; } if (Event.current.button == 0) { result = DragHandleResult.LMBDrag; } else if (Event.current.button == 1) { result = DragHandleResult.RMBDrag; } s_DragHandleHasMoved = true; GUI.changed = true; Event.current.Use(); } break; case EventType.Repaint: Color currentColour = Handles.color; if (id == GUIUtility.hotControl && s_DragHandleHasMoved) { Handles.color = colorSelected; } Handles.matrix = Matrix4x4.identity; capFunc(id, screenPosition, Quaternion.identity, handleSize); Handles.matrix = cachedMatrix; Handles.color = currentColour; break; case EventType.Layout: Handles.matrix = Matrix4x4.identity; HandleUtility.AddControl(id, HandleUtility.DistanceToCircle(screenPosition, handleSize)); Handles.matrix = cachedMatrix; break; } return(position); }
public static Vector3 DraggableHandle(Vector3 position, float handleSize, Quaternion rotation, Handles.CapFunction capFunc, Color colorSelected, out DragHandleResult result, bool allowRightButton = false) { result = DragHandleResult.None; int id = GUIUtility.GetControlID(DragHandleHash, FocusType.Passive); LastDragHandleId = id; Vector3 screenPosition = Handles.matrix.MultiplyPoint(position); Matrix4x4 cachedMatrix = Handles.matrix; bool leftMouseUsed = Event.current.button == 0; bool rightMouseUsed = Event.current.button == 1; bool validControl = leftMouseUsed || (rightMouseUsed && allowRightButton); switch (Event.current.GetTypeForControl(id)) { case EventType.MouseDown: if (HandleUtility.nearestControl == id && validControl) { GUIUtility.hotControl = id; Event.current.Use(); EditorGUIUtility.SetWantsMouseJumping(1); result = leftMouseUsed ? DragHandleResult.LMBPress : DragHandleResult.RMBPress; _dragHandleMouseCurrent = _dragHandleMouseStart = Event.current.mousePosition; _dragHandleWorldStart = position; _dragHandleHasMoved = false; } break; case EventType.MouseUp: if (GUIUtility.hotControl == id && validControl) { GUIUtility.hotControl = 0; Event.current.Use(); EditorGUIUtility.SetWantsMouseJumping(0); result = leftMouseUsed ? DragHandleResult.LMBRelease : DragHandleResult.RMBRelease; if (Event.current.mousePosition == _dragHandleMouseStart) { bool doubleClick = (_dragHandleClickId == id) && (Time.realtimeSinceStartup - _dragHandleClickTime < DragHandleDoubleClickInterval); _dragHandleClickId = id; _dragHandleClickTime = Time.realtimeSinceStartup; if (!doubleClick) { result = leftMouseUsed ? DragHandleResult.LMBClick : DragHandleResult.RMBClick; } else { result = leftMouseUsed ? DragHandleResult.LMBDoubleClick : DragHandleResult.RMBDoubleClick; } } } break; case EventType.MouseDrag: if (GUIUtility.hotControl == id && validControl) { _dragHandleMouseCurrent += new Vector2(Event.current.delta.x, -Event.current.delta.y); Vector3 position2 = Camera.current.WorldToScreenPoint(Handles.matrix.MultiplyPoint(_dragHandleWorldStart)) + (Vector3)(_dragHandleMouseCurrent - _dragHandleMouseStart); position = Handles.matrix.inverse.MultiplyPoint(Camera.current.ScreenToWorldPoint(position2)); if (Camera.current.transform.forward == Vector3.forward || Camera.current.transform.forward == -Vector3.forward) { position.z = _dragHandleWorldStart.z; } if (Camera.current.transform.forward == Vector3.up || Camera.current.transform.forward == -Vector3.up) { position.y = _dragHandleWorldStart.y; } if (Camera.current.transform.forward == Vector3.right || Camera.current.transform.forward == -Vector3.right) { position.x = _dragHandleWorldStart.x; } result = leftMouseUsed ? DragHandleResult.LMBDrag : DragHandleResult.RMBDrag; _dragHandleHasMoved = true; GUI.changed = true; Event.current.Use(); } break; case EventType.Repaint: Color currentColour = Handles.color; if (id == GUIUtility.hotControl && _dragHandleHasMoved) { Handles.color = colorSelected; } Handles.matrix = Matrix4x4.identity; capFunc(id, screenPosition, rotation, handleSize, EventType.Repaint); Handles.matrix = cachedMatrix; Handles.color = currentColour; break; case EventType.Layout: Handles.matrix = Matrix4x4.identity; HandleUtility.AddControl(id, HandleUtility.DistanceToCircle(screenPosition, handleSize)); Handles.matrix = cachedMatrix; break; } return(position); }
public static Vector3 DraggableHandle(Vector3 position, out DragHandleResult result) { return(DraggableHandle(position, .5f, Quaternion.identity, Handles.SphereHandleCap, Color.green, out result)); }
public static Vector3 DragHandle(Vector3 position, float handleSize, Handles.CapFunction capFunc, Color colorSelected, out DragHandleResult result)
private static Vector3 DoDragHandleAxis(DragAxisInfo axisInfo, Vector3 position, ref DragHandleResult result) { // Must request a control ID for each interactible control in the GUI that can respond to events int id = GUIUtility.GetControlID(axisInfo._handleHash, FocusType.Passive); float handleSize = HandleUtility.GetHandleSize(position); Camera camera = Camera.current; Event currentEvent = Event.current; Vector2 mousePos = HEU_EditorUI.GetMousePosition(ref currentEvent, camera); Vector3 handlePosition = Handles.matrix.MultiplyPoint(position); Matrix4x4 cachedHandleMatrix = Handles.matrix; int mouseButtonID = Event.current.button; // Process events (using GetTypeForControl to filter events relevant to this control) switch (currentEvent.GetTypeForControl(id)) { case EventType.MouseDown: { if (HandleUtility.nearestControl == id && (mouseButtonID == 0 || mouseButtonID == 1)) { GUIUtility.hotControl = id; axisInfo._dragMouseCurrent = axisInfo._dragMouseStart = mousePos; axisInfo._dragWorldStart = position; axisInfo._handleHasMoved = false; currentEvent.Use(); EditorGUIUtility.SetWantsMouseJumping(1); if (mouseButtonID == 0) { result = DragHandleResult.LMB_PRESS; } else if (mouseButtonID == 1) { result = DragHandleResult.RMB_PRESS; } } break; } case EventType.MouseUp: { if (GUIUtility.hotControl == id && (mouseButtonID == 0 || mouseButtonID == 1)) { GUIUtility.hotControl = 0; currentEvent.Use(); EditorGUIUtility.SetWantsMouseJumping(0); if (mouseButtonID == 0) { result = DragHandleResult.LMB_RELEASE; } else if (mouseButtonID == 1) { result = DragHandleResult.RMB_RELEASE; } // Double-click if (mousePos == axisInfo._dragMouseStart) { bool doubleClick = (axisInfo._handleClickID == id) && (Time.realtimeSinceStartup - axisInfo._handleClickTime < _handleDoubleClikcInterval); axisInfo._handleClickID = id; axisInfo._handleClickTime = Time.realtimeSinceStartup; if (mouseButtonID == 0) { result = doubleClick ? DragHandleResult.LMB_DOUBLECLICK : DragHandleResult.LMB_CLICK; } else if (mouseButtonID == 1) { result = doubleClick ? DragHandleResult.RMB_DOUBLECLICK : DragHandleResult.RMB_CLICK; } } } break; } case EventType.MouseDrag: { if (GUIUtility.hotControl == id) { if (axisInfo._dragAxis == DragAxis.ALL_AXIS) { // Free movement - (all axis) // Flip y because Unity is inverted axisInfo._dragMouseCurrent += new Vector2(currentEvent.delta.x, -currentEvent.delta.y); Vector3 position2 = camera.WorldToScreenPoint(Handles.matrix.MultiplyPoint(axisInfo._dragWorldStart)) + (Vector3)(axisInfo._dragMouseCurrent - axisInfo._dragMouseStart); position = Handles.matrix.inverse.MultiplyPoint(camera.ScreenToWorldPoint(position2)); } else { // Linear movement (constraint to current axis) // Get the delta between the original handle position and the original mouse down position // This is used to substract from relative mouse movement to counter the handle jump when dragging Vector3 originalDragStartSS = HEU_EditorUI.GetHandleWorldToScreenPosition(axisInfo._dragWorldStart, camera); Vector3 deltaOriginalDragOffset = axisInfo._dragMouseStart - new Vector2(originalDragStartSS.x, originalDragStartSS.y); Vector3 startPosSS = HEU_EditorUI.GetHandleWorldToScreenPosition(position, camera); Vector3 constraintSS = HEU_EditorUI.GetHandleWorldToScreenPosition(position + axisInfo._direction, camera) - startPosSS; Vector3 mousePosV3 = mousePos; Vector3 relativeMousePos = mousePosV3 - startPosSS - deltaOriginalDragOffset; float projection = Vector3.Dot(relativeMousePos, constraintSS.normalized); float normalization = 1 / constraintSS.magnitude; float scale = projection * normalization; position += axisInfo._direction * scale; } if (mouseButtonID == 0) { result = DragHandleResult.LMB_DRAG; } else if (mouseButtonID == 1) { result = DragHandleResult.RMB_DRAG; } axisInfo._handleHasMoved = true; GUI.changed = true; currentEvent.Use(); } break; } case EventType.MouseMove: case EventType.Repaint: { Color handleColor = Handles.color; if ((GUIUtility.hotControl == id && axisInfo._handleHasMoved) || (HandleUtility.nearestControl == id)) { Handles.color = Color.yellow; } else { Handles.color = axisInfo._axisColor; } Handles.matrix = Matrix4x4.identity; if (axisInfo._dragAxis == DragAxis.ALL_AXIS) { HEU_EditorUI.DrawCubeCap(id, handlePosition, Quaternion.identity, handleSize * 0.25f); } else { HEU_EditorUI.DrawArrowCap(id, handlePosition, Quaternion.LookRotation(axisInfo._direction), handleSize); } Handles.matrix = cachedHandleMatrix; Handles.color = handleColor; // This forces a Repaint. We want this when we change the axis color due to being cursor being nearest. if (currentEvent.type == EventType.MouseMove && HandleUtility.nearestControl == id) { SceneView.RepaintAll(); } break; } case EventType.Layout: { // AddControl tells Unity where each Handle is relative to the current mouse position Handles.matrix = Matrix4x4.identity; if (axisInfo._dragAxis == DragAxis.ALL_AXIS) { float distance = handleSize * 0.3f; HandleUtility.AddControl(id, HandleUtility.DistanceToCircle(handlePosition, distance)); } else { HandleUtility.AddControl(id, HandleUtility.DistanceToLine(handlePosition, handlePosition + axisInfo._direction * handleSize) * 0.4f); } Handles.matrix = cachedHandleMatrix; break; } } return(position); }
// LOGIC ------------------------------------------------------------------------------------------------------ public static Vector3 DoDragHandle(Vector3 position, bool bEnableAxisX, bool bEnableAxisY, bool bEnableAxisZ, bool bEnableAxisAll, out DragHandleResult result) { result = DragHandleResult.NONE; if (bEnableAxisAll) { position = DoDragHandleAxis(_axisInfoAll, position, ref result); } if (bEnableAxisX && result == DragHandleResult.NONE) { position = DoDragHandleAxis(_axisInfoX, position, ref result); } if (bEnableAxisY && result == DragHandleResult.NONE) { position = DoDragHandleAxis(_axisInfoY, position, ref result); } if (bEnableAxisZ && result == DragHandleResult.NONE) { position = DoDragHandleAxis(_axisInfoZ, position, ref result); } return(position); }