Godot:CustomDrawing
lastmod 2022-05-22created 2020-11-088 edits
How to do custom drawing.
Categories
- Hexagon#Godot - explains how to draw a cube with custom drawing in Godot.
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.
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);
}
}