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:
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);
}
...
