In this article, I will show you how to create a circular progress bar. By using a circular progress bar instead of the usual portrait or landscape orientation, you can add a little accent to your screen, so please refer to this tutorial if you find a use for it. At the end of the tutorial, we will also show you some sample progress bars that are not circular (e.g., heart-shaped), so if you are interested, please take a look at them as well.
The final project file for this tutorial is available at GitHub repository . If you download the .zip file and import the âproject.godotâ file in the âEndâ folder with the Godot Engine, you can check the project directly.
Environment
ă»Godot version: 3.4.4
ă»Computer OS version: macOS 11.6.5
Other Articles
Please also use the following articles to help you start creating your game.
Downloading Godot
Project Manager of Godot
Preparation
Preparing an image of the circular progress bar
If you have a drawing application such as Photoshop or GIMP on your computer, you can use it. I will not go into the details of how to use drawing applications here. If you have difficulty, please Google it.
Create a circle with the center hollowed out. At this time, the color of the circle should be white. The reason is that the color can be easily set in the Godot editor. The rest of the image should be transparent. Save the image as a png file with the image size set to 300 px in height and width.
In my case, I copied a graphic object created with the âKeynoteâ application on Mac (a slide show creation application similar to PowerPoint on Windows PC) to the clipboard, launched the âPreviewâ application, created a new image from the clipboard, and saved it as a png.
If you want to skip this step, I hope you can download the image below directly from your browser (if the background is white, the image may assimilate and look like nothingâŠ)
Creating a new project
Start Godot Engine and create a new project. You can name your project as you like. If you canât think of one, letâs call it âCircular Progress Barâ.
Importing the prepared images.
Create a âTexturesâ folder directly under the resource folder (res://) in the file system dock. Drag and drop the circular image you have just prepared and import it there. The file name should be âCircularProgressBar.pngâ (file path is res://Textures/CircularProgressBar.png).
Create a scene
First, letâs create a CircularProgressBar scene.
Select âSceneâ menu > âNew Sceneâ.
Select the âControlâ class node as the root node and rename it to âCircularProgressBarâ.
Save the scene at this point. Save the scene with the file path âres://CircularProgressBar.tscnâ.
Continue adding a âTextureProgressâ node to the âCircularProgressBarâ root node
Furthermore, add a âLabelâ node to the âCircularProgressBarâ root node.
The scene tree should now look like this:
Edit Node
CircularProgressBar (Control) Root node
- In the 2D workspace, select âFull Screenâ from the toolbar > âLayoutâ.
TextureProgress node
- In the Inspector, set the âFill Modeâ property to âClockwiseâ. This is the style in which the progress bar progresses in a clockwise direction. Be sure to select this property appropriately for the shape of the progress bar. For example, if you have a heart-shaped progress bar, âBottom to Topâ would be appropriate, where the bar progresses from bottom to top.
- Drag and apply the image resource âres://Textures/CircularProgressBar.pngâ imported earlier to the âTextureâ > âUnderâ property.
- Do the same for the âTextureâ > âProgressâ property.
- Set the color of the Tint > Under property to #000000 (black).
- Leave the âTintâ>âProgressâ property at the default color #ffffff (white) for the time being, even though it is not very appealing.
- In the 2D workspace, select âCenterâ from the toolbar > âLayoutâ.
Label node
- In the inspector, enter an appropriate initial value such as â100%â for the âTextâ property.
- Set the âAlignâ property to âCenterâ.
- Set the âValignâ property to âCenterâ as well.
Downloading Open Font Package
Since we want to set a font for the âLabelâ node, letâs switch to the âAsset Libraryâ tab at the top of the editor and download the âOpen Font Packageâ.
- Click the âAssetLibâ tab at the top and switch to âAsset Library.
- Search for âfontâ to find âOpen Font Packageâ and click it.
- Click âDownloadâ.
- Check only the necessary font files and click âInstallâ. This time, select âXolonium-Bold.ttfâ.
- If it appears in the file system dock, you are done.
Label node (continued)
- Return to the inspector and apply a new âDynamicFontâ to the âTheme Overridesâ > âFontsâ > âFontâ property.
- Expand the applied âDynamicFontâ resource and apply the font resource âres://fonts/xolonium/xolonium-fonts-4.1/ttf/Xolonium-Bold. ttfâ is applied.
- Set the âSettingsâ > âSizeâ property of the same âDynamicFontâ resource to 40.
- Set the âSettingsâ > âOutline Sizeâ property of the same âDynamicFontâ resource to 4.
- Go back a little and enable âTheme Overridesâ > âColorsâ > âFont Colorâ and leave the color as #000000 (black).
- In the 2D workspace, select âCenterâ from the âLayoutâ on the toolbar.
Attaching and coding a script
Updating the progress bar with the up/down arrow keys
Letâs code a script to change the value of the progress bar with the up and down arrow keys on the keyboard. By changing the value of the âValueâ property of the âTextureProgressâ node, the display range of the âTextureâ > âProgressâ property will also change.
- Attach a script to the âCircularProgressBarâ root node. Name the file âProgress.gdâ and specify the file path as âres://Progress.gdâ.
- When the editor opens, edit as follows.
###Progress.gd###
extends Control
# referencing the TextureProgress node
onready var progress_bar = $TextureProgress
# referencing a Label node
onready var label = $Label
func _ready():
# reset the value property of the TextureProgress node to 0
progress_bar.value = 0
func _process(delta):
# call a method to process the input operation
get_input()
# call a method to update the Label node's Text property
update_label()
# method to process the input operation
func get_input():
# if we press the up arrow key
if Input.is_action_pressed("ui_up"):
# add 1 to the value of the Value property of the TextureProgress node
progress_bar.value += 1
# if we press the down arrow key
if Input.is_action_pressed("ui_down"):
# Minus 1 from the value of the Value property of the TextureProgress node
progress_bar.value -= 1
# Method to update the text property of the Label node
func update_label():
# Display the value of the Value property of the TextureProgress node with a %
label.text = str(progress_bar.value) + "%"
Now letâs run the project and use the up and down arrow keys to change the value of the progress bar. If you are running the project for the first time, just set the current scene as the main scene in the dialog that prompts you to select the main scene.
Changing the color of the progress bar
Since monochrome is not very appealing, letâs change the color of the progress bar as well. This time, we want the color of the progress bar to change gradually as the value of the progress bar changes. To make the update of the âValueâ property of the âTextureProgressâ node finer, letâs decrease the value of the âStepâ property. In this case, we set it to 0.1.
The script should be edited as follows.
###Progress.gd###
extends Control
# properties specifying the beginning and ending values of the h, s, and v properties of
# the tint_progress property of the TextureProgress node (color is specified by HSV)
export (float) var h_start = 0.0
export (float) var h_end = 0.45
export (float) var s_start = 0.3
export (float) var s_end = 1.0
export (float) var v_start = 0.3
export (float) var v_end = 1.0
onready var progress_bar = $TextureProgress
onready var label = $Label
func _ready():
progress_bar.value = 0
func _process(delta):
get_input()
update_label()
# Added: call a method to update color of the bar
update_color()
func get_input():
if Input.is_action_pressed("ui_up"):
progress_bar.value += 1
if Input.is_action_pressed("ui_down"):
progress_bar.value -= 1
func update_label():
label.text = str(progress_bar.value) + "%"
# Added: method to update color of the bar
func update_color():
# Change the hue of the progress bar as the value of the Value property changes from min to max.
progress_bar.tint_progress.h = range_lerp(progress_bar.value, progress_bar.min_value, progress_bar.max_value, h_start, h_end)
# Change the saturation of the progress bar as the value of the Value property changes from min to max.
progress_bar.tint_progress.s = range_lerp(progress_bar.value, progress_bar.min_value, progress_bar.max_value, s_start, s_end)
# Change the brightness of the progress bar as the value of the Value property changes from min to max.
progress_bar.tint_progress.v = range_lerp(progress_bar.value, progress_bar.min_value, progress_bar.max_value, v_start, v_end)
Now letâs run the project again.
Although a change in color would be beautiful, we want to keep in mind that the design is only for the game.
Progress bar in various shapes
As you may have noticed after implementing the above, a progress bar can be applied in various ways as long as you have the image resource that serves as the shape of the progress bar.
By duplicating âCircularProgressBar.tscnâ and modifying its properties, it is relatively easy to create progress bars with various patterns. We have prepared some samples for your viewing.
Heart-shaped progress bar
Each property of âScript Variablesâ in the root node. Hue is from purple to red. Saturation and lightness are increased from the beginning.
âFill Modeâ property of the âTextureProgressâ node. Progress from bottom to top.
âTexturesâ > âUnderâ/âProgressâ property of the âTextureProgressâ node. Apply heart texture.
Run the scene.
Skull-shaped progress bar
Each property of âScript Variablesâ in the root node. Hue is from green to blue. Saturation is kept low.
âFill Modeâ property of the âTextureProgressâ node. Both up and down from the center.
âTexturesâ > âUnderâ / âProgressâ property of the âTextureProgressâ node. Apply a skull type texture.
Run the scene.
Flask progress bar
In this sample, the âProgress.gdââ script is edited a bit.
### Progress.gd###
# Added: bar limit (default value is 100 to match max_value)
export (float) var value_limit = 100
# Methods for input operation processing
func get_input():
if Input.is_action_pressed("ui_up"):
progress_bar.value += 1
# Added: only allow the bar to progress up to its limit value
progress_bar.value = min(progress_bar.value, value_limit)
if Input.is_action_pressed("ui_down"):
progress_bar.value -= 1
# Method to update the text property of a Label node
func update_label():
# Added: calculate Label's % with the bar's limit value as 1
var actual_value = floor(progress_bar.value / value_limit * 100)
label.text = str(actual_value) + "%"
Each property of âScript Variablesâ in the root node. Here, the value of the newly added property âValue Limitâ is changed to 72.5. This is the value that corresponds to the top scale on the flask texture image that will be applied later.
âFill Modeâ property of the âTextureProgressâ node. From bottom to top.
âTexturesâ > âUnderâ / âProgressâ property of the âTextureProgressâ node. Apply flask texture.
Run the scene. With the above adjustments, the bar stops progressing at the top scale of the flask texture.
Brain Progress Bar.
Each property of the root node âScript Variablesâ.
âFill Modeâ property of the âTextureProgressâ node.
âTexturesâ > âUnderâ / âProgressâ property of the âTextureProgressâ node.
In the âTextureProgressâ node, âRadial Fillâ > âFill Degreesâ was set to 180, so that the maximum angle at which the progression bar can be expanded is 180°. The y value of âCenter Offsetâ was set to 130 to shift the center of rotation of the progression bar to just below the brain texture.
Run the scene.
Letâs combine what we have created so far into one scene.
This is what it looks like when you run the project after changing the main scene settings.
Conclusion
In this article, you learned how to create circular progress bars and other shapes of progress bars. The main points are as follows.
- The shape of the progress bar is determined by the image resource for the texture.
- The âFill Modeâ property of the âTextureProgressâ node is used to set the direction of the barâs progress according to its shape.
- By changing the value of the âValueâ property of the âTextureProgressâ node in a script, the progress bar can also be linked.
- By changing the color of the âTintâ > âProgressâ property of the âTextureProgressâ node in the script, the color of the bar can be changed according to its progress.
References
- YouTube: Godot Circle Progress Bar Chart
- YouTube: Creating a circular meter using a single Godot Control Node