I am making a node-based custom editor window (something like the animator window). I now can draw nodes and edges between them. The thing I want to do now is to draw a triangle arrowhead in the middle of the edge (like the one you see in the animator window). From this post , I started to try GL to draw the triangle. Here’s my code:
private void OnGUI()
{
// Do other stuff...
Vector2 startPos = ...; // The start position (Center of the from node. This is from the node's rect which mean it used the rect's coordinate system)
Vector2 endPos = ...; // The end position (Center of the to node. Also from a rect)
Vector2 center = MathUtils.Average(startPos, endPos); // The center of the current edge
Vector2 dir = (endPos - startPos).normalized; // The direction of the current egde
// Making an equilateral triangle
Vector3 a = center + dir * 10; // From the center move 10 more unit along the line's direction
Vector3 b = center + Rotate(dir, 120 * Mathf.Deg2Rad) * 10; // Rotate the dir 120 degree and move along that direction 10 more unit
Vector3 c = center + Rotate(dir, -120 * Mathf.Deg2Rad) * 10; // Rotate the dir -120 degree and move along that direction 10 more unit
// The coordinate of the GUI is (0, 0) on the top left conner, this will convert it to the normal GL coordinate ((0, 0) on the bottom left connor)
// Also the position property is a inheritance property from the EditorWindow (in case you don't know)
a.y = position.height - a.y;
b.y = position.height - b.y;
c.y = position.height - c.y;
// InverseLerp will return the value from [(0, 0), (1, 1)] because that what GL.Vertex() use
a = InverseLerp(Vector2.zero, position.size, a);
b = InverseLerp(Vector2.zero, position.size, b);
c = InverseLerp(Vector2.zero, position.size, c);
DrawGLTriangle(a, b, c); // Draw the triangle
Handles.DrawAAPolyLine(10, startPos, endPos); // Draw the egde between the two current nodes
// Do other stuff...
}
public static Vector2 InverseLerp(Vector2 start, Vector2 end, Vector2 value)
{
return (value - start) / (end - start);
}
public static Vector2 Rotate(Vector2 v, float angle)
{
return new Vector2(
v.x * Mathf.Cos(angle) - v.y * Mathf.Sin(angle),
v.x * Mathf.Sin(angle) + v.y * Mathf.Cos(angle)
);
}
// This function is directly taken from Unity https://docs.unity3d.com/ScriptReference/GL.TRIANGLES.html
public static void DrawGLTriangle(Vector3 a, Vector3 b, Vector3 c)
{
GL.PushMatrix();
GL.LoadOrtho();
GL.Begin(GL.TRIANGLES);
GL.Vertex(a);
GL.Vertex(b);
GL.Vertex(c);
GL.End();
GL.PopMatrix();
}
Here’s the result, the triangle is not on the line. Its x position seems correct but the y position is a little higher than it should be. It seems to rotate correctly.