How to detect events in a line made with Handles.DrawBezier?

Viewed 35

I'm trying to detect clicks on a line used to connect nodes in node graphs. I create those lines with Handles.DrawBezier, but it does not appear that it supports events. I tried to create a Rect in the same position as the corresponding line but I couldn't rotate the Rect to match its position with the line. It appears like this right now:

enter image description here

So now I'm kinda confused on what I should do. Here's the code of the Line class that I use to draw the Line and where I would like to detect and handle events (specially PressDown event):

public abstract class Line : ScriptableObject
    {
        [HideInInspector] public string id;
        [HideInInspector] public Node parent;
        [HideInInspector] public Node children;
        public Rect lineRect;
        
        // Line values
        private const float lineWidth = 3f;
        private const float lineArrowSize = 5f;
        private const float dashSize = 4f;
    
        // Rect values
        private const float rectWidth = 7f;
    
        public abstract LineTypes LineType
        {
            get;
        }
    
        public void Draw(StoryBuilderLocalGraphSO localGraph)
        {
            Node parentLocalNode = localGraph.GetLocalNode(parent.id);
            Node childLocalNode = localGraph.GetLocalNode(children.id);
    
            Vector2 startPosition = parentLocalNode.rect.center;
            Vector2 endPosition = childLocalNode.rect.center;
    
            // if the Line is a Conditional Branch
            if (LineType == LineTypes.ConditionalBranch)
            {
                // draw it as a dotted line with an arrow
                DrawArrow(startPosition, endPosition);
                Handles.DrawDottedLine(startPosition, endPosition, dashSize);
            }
            // if the Line is a Branch
            else if (LineType == LineTypes.Branch)
            {
                // draw it as a straight line with an arrow
                DrawArrow(startPosition, endPosition);
                Handles.DrawBezier(startPosition, endPosition, startPosition, endPosition, Color.white, null, lineWidth);
            }
            // if the Line is a Connecting Line
            else if(LineType == LineTypes.ConnectingLine)
            {
                // draw it as a straight line without an arrow
                Handles.DrawBezier(startPosition, endPosition, startPosition, endPosition, Color.white, null, lineWidth);
            }
    
            lineRect = GetLineRect(startPosition, endPosition);
    
            var localNodeStyle = new GUIStyle();
    
            localNodeStyle.normal.background = EditorGUIUtility.Load("node1") as Texture2D;
    
            GUILayout.BeginArea(lineRect, localNodeStyle);
            EditorGUILayout.LabelField("Line");
            GUILayout.EndArea();
    
            GUI.changed = true;
        }
    
        private Rect GetLineRect(Vector2 startPosition, Vector2 endPosition)
        {
            // The distance between the parent node center and the child node center
            float distance = Vector2.Distance(startPosition, endPosition);
            // The scale represents the center of the rectangle.
            Vector2 scale = (startPosition+endPosition)/2;
    
            return new Rect(Mathf.Abs(scale.x), Mathf.Abs(scale.y), rectWidth, distance);
        }
    
        private void DrawArrow(Vector2 startPosition, Vector2 endPosition)
        {
            // calculate midway position
            Vector2 midPosition = (endPosition + startPosition) / 2f;
    
            // Vector from start to end position of line 
            Vector2 direction = endPosition - startPosition;
    
            // Calculate normalised perpendicular positions from the mid point
            Vector2 arrowTailPoint1 = midPosition - new Vector2(-direction.y, direction.x).normalized * lineArrowSize;
            Vector2 arrowTailPoint2 = midPosition + new Vector2(-direction.y, direction.x).normalized * lineArrowSize;
    
            // Calculate mid point offset position for arrow head
            Vector2 arrowHeadPoint = midPosition + direction.normalized * lineArrowSize;
    
            // Draw arrow
            Handles.DrawBezier(arrowHeadPoint, arrowTailPoint1, arrowHeadPoint, arrowTailPoint1, Color.white, null, lineArrowSize);
            Handles.DrawBezier(arrowHeadPoint, arrowTailPoint2, arrowHeadPoint, arrowTailPoint2, Color.white, null, lineArrowSize);
        }
    ...
0 Answers
Related