Ejemplo n.º 1
0
        /// <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;
        }
Ejemplo n.º 2
0
    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));
 }
Ejemplo n.º 5
0
 public static Vector3 DragHandle(Vector3 position, float handleSize, Handles.CapFunction capFunc, Color colorSelected, out DragHandleResult result)
Ejemplo n.º 6
0
        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);
        }
Ejemplo n.º 7
0
        // 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);
        }