Skip to content
Search

Godot:CustomDrawing

lastmod 2022-05-22created 2020-11-088 edits

How to do custom drawing.

Categories

Features

Custom drawing in 2D nodes is really useful. Here are some use cases:

  • Drawing shapes or logic that existing nodes can't do, such as an image with trails or a special animated polygon.
  • Visualizations that are not that compatible with nodes, such as a Tetris board. (The Tetris example uses custom drawing functions to draw blocks.)
  • Drawing a large number of simple objects. Custom drawing avoids the overhead of using a large number of nodes, possibly lowering memory usage and improving performance.
  • Making a custom UI control. There are plenty of controls available, but when you have unusual needs, you will likely need a custom control.

Draw Method

Just override the _Draw() function.

public override void _Draw()
{
    // Your draw commands here
}

See CanvasItem for drawing methods.

Updating

The _draw() function is called only once, and then the draw commands are cached and remembered, so further calls are unnecessary.

If redrawing is needed because a state or something else changed, call CanvasItem.update() in that same node and a new _draw() call will happen.

Here is a slightly more complex example, where a texture variable is redrawn when modified:

public class CustomNode2D : Node2D
{
    private Texture _texture;
    public Texture Texture
    {
        get
        {
            return _texture;
        }

        set
        {
            _texture = value;
            Update();
        }
    }

    public override void _Draw()
    {
        DrawTexture(_texture, new Vector2());
    }
}

In some cases, it may be desirable to draw every frame. For this, call update() from the _process() callback, like this:

public class CustomNode2D : Node2D
{
    public override void _Draw()
    {
        // Your draw commands here
    }

    public override void _Process(float delta)
    {
        Update();
    }
}

Example

public class CustomNode2D : Node2D
{
    public void DrawCircleArc(Vector2 center, float radius, float angleFrom, float angleTo, Color color)
    {
        int nbPoints = 32;
        var pointsArc = new Vector2[nbPoints];

        for (int i = 0; i < nbPoints; ++i)
        {
            float anglePoint = Mathf.Deg2Rad(angleFrom + i * (angleTo - angleFrom) / nbPoints - 90f);
            pointsArc[i] = center + new Vector2(Mathf.Cos(anglePoint), Mathf.Sin(anglePoint)) * radius;
        }

        for (int i = 0; i < nbPoints - 1; ++i)
            DrawLine(pointsArc[i], pointsArc[i + 1], color);
    }

    public override void _Draw()
    {
        var center = new Vector2(200, 200);
        float radius = 80;
        float angleFrom = 75;
        float angleTo = 195;
        var color = new Color(1, 0, 0);
        DrawCircleArc(center, radius, angleFrom, angleTo, color);
    }
}

See also

Favorite site

author Zer0 sitemap