This tutorial covers how to create a spinning or indeterminate progress bar using the Godot Engine. Progress bars are easily created using the TextureProgress control node, but a little more work is needed to create one with a spinning or indeterminate effect.


Radial Progress Bar

To create a radial or circular progress bar, first create a TextureProgress control node. This node is specifically for creating progress bars and already has properties for handling standard linear progress bars along with radial progress bars.

Set the Fill Mode property to Clockwise or Counter Clockwise.

Fill Mode

Add a texture to the Progress property in the Textures section. Under and over textures can also be added to further customize the look of your progress bar.

Progress Texture

Then with the remaining default values, setting the Value property under the Range section will fill in the progress bar to the correct position.

Radial Progress

Spinning Progress Bar

Creating a spinning progress bar involves modifying and animating some of the TextureProgress properties.

First set the Range/Value property to 100, leaving the remaining properties as their default values.

Range Values

Change the Fill Degrees property under Radial Fill to the desired length of your spinner.

Fill Degrees

Now when the Initial Angle property is modified, the progress bar will appear to rotate.

Initial Angle

Animating the Spinner

Add a script to the TextureProgress node with the following contents.

func _ready() -> void:
	var tween: SceneTreeTween = get_tree().create_tween().set_loops()
	tween.tween_property(self, "radial_initial_angle", 360.0, 1.5).as_relative()

This creates a new tween on the scene tree that animates the radial_initial_angle property of the TextureProgress node. The set_loops() ensures the tween loops indefinitely.

The tween_property method defines the animation of the radial_initial_angle to the value of 360.0 in 1.5 seconds. The property is defined on self since the script is attached directly to the TextureProgress node. If your script is on a different node, ensure the path to the TextureProgress node is included here.

The as_relative() function ensures the property is modified relative to its current value. This means that the property is always trying to change 360 degrees from its current value, instead of stopping when the initial angle value hits 360 degrees.

Now you should have an animated spinner!