今回は、円形のプログレスバーの作り方を紹介する。プログレスバーを、一般的な縦向きや横向きではなく、円形にすることによって、画面上のちょっとしたアクセントにもなるので使い所があれば是非参考にしていただきたい。また、チュートリアルの最後のほうで、円形以外の形状(例えばハート型)のプログレスバーもサンプルとしていくつか紹介するのでそちらも興味があればぜひご覧いただきたい。
このチュートリアルで最後にできあがるプロジェクトのファイルはGitHubリポジトリ
に置いている。.zipファイルをダウンロードしていただき、「End」フォルダ内の「project.godot」ファイルを Godot Engine でインポートしていただければ、直接プロジェクトを確認していただくことも可能だ。
Environment
Godot のバージョン: 3.4.4
コンピュータのOS: macOS 11.6.5
Basic Articles
以下の記事もお役立てください。
Godot をダウンロードする
Godot のプロジェクトマネージャー
Godot の言語設定
準備
円形プログレスバーの画像を用意する
お使いのコンピュータに Photoshop や GIMP などの描画アプリがあれば、そちらをお使いいただければOKだ。描画アプリの使い方の詳細はここでは割愛させていただく。難しい場合はググってみてほしい。
真ん中をくり抜いた円の図形を作成する。この時、円の色は白にする。理由は Godot エディタ上で色の設定が簡単にできるだからだ。白以外の部分は透過させた状態にしておく。画像サイズを縦横 300 px にして png ファイルとして保存する。
ちなみに私の場合は、Mac の「Keynote」アプリ(Windows PC の PowerPointのようなスライドショー作成アプリ)で作成した図形オブジェクトをクリップボードにコピーして、「プレビュー」アプリを起動して、「クリップボードから新規作成」して、png として保存した。
この手順を省略したい場合は、下の画像をブラウザから直接ダウンロードしていただければと思う(背景が白いと画像が同化して何もないように見えるかもしれない…)。
新規プロジェクトを作成する
それでは Godot Engine を立ち上げて、新規プロジェクトを作成しよう。プロジェクトの名前はあなたのお好みで決めていただいてOKだ。もし思いつかなければ「Circular Progress Bar」としておこう。
用意した画像をインポートする
ファイルシステムドックで先にリソースフォルダ直下(res://)に「Textures」フォルダを作成する。そこにさきほど用意した円形の画像をドラッグ&ドロップしてインポートする。ファイル名は「CircularProgressBar.png」としておく(ファイルパスは res://Textures/CircularProgressBar.png )。
シーンを作る
まずは CircularProgressBar シーンを作ろう。
「シーン」メニュー>「新規シーン」を選択する。
「Control」クラスのノードをルートノードとして選択したら、名前を「CircularProgressBar」に変更する。
一旦ここでシーンを保存する。ファイルパスを「res://CircularProgressBar.tscn」としてシーンを保存する。
続けて「CircularProgressBar」ルートノードに「TextureProgress」ノードを追加する。
さらに「CircularProgressBar」ルートノードに「Label」ノードを追加する。
シーンツリーは以下のようになったはずだ。
ノードを編集する
CircularProgressBar (Control) ルートノード
- 2D ワークスペースで、ツールバー>「レイアウト」から「全画面」を選択する。
TextureProgress ノード
- インスペクターにて、「Fill Mode」プロパティの値を「Clockwise」にする。これは時計回りにぐるりとプログレスバーが進行するスタイルだ。このプロパティはプログレスバーの形状に合わせて適切に選択することを心がけたい。例えば、もしハート型のプログレスバーなら下から上にバーが進行する「Bottom to Top」が相応しいだろう。
- 「Texture」>「Under」プロパティに先にインポートしておいた画像リソース「res://Textures/CircularProgressBar.png」をドラッグして適用しよう。
- 「Texture」>「Progress」プロパティも同様にする。
- 「Tint」>「Under」プロパティの色を #000000 (黒) にする。
- 「Tint」>「Progress」プロパティは、味気ないが、ひとまずデフォルトの #ffffff (白) のままにしておく
- 2D ワークスペースで、ツールバー>「レイアウト」から「中央」を選択する。
Label ノード
- インスペクターにて「Text」プロパティには初期値として適当に「100%」などと入力しておく。
- 「Align」プロパティを「Center」にする。
- 「Valign」プロパティも「Center」にする。
Open Font Package をダウンロードする
「Label」ノードにフォントを設定したいので、エディタ上部のタブで「Asset Library」に切り替えて「Open Font Package」をダウンロードしよう。
- 上部の「AssetLib」タブをクリックして「Asset Library」に切り替える。
- 「font」で検索するなどして「Open Font Package」を見つけたら、それをクリックする。
- 「Download」をクリックする。
- 必要なフォントファイルだけチェックして「Install」をクリックする。今回は「Xolonium-Bold.ttf」を選択。
- ファイルシステムドックに表示されれば完了だ。
Label ノード(続き)
- インスペクターに戻って、「Theme Overrides」>「Fonts」>「Font」プロパティに「新規 DynamicFont」を適用する。
- 適用した「DynamicFont」リソースを展開し、「Font」>「Font Data」プロパティにインストールしたばかりのフォントリソース「res://fonts/xolonium/xolonium-fonts-4.1/ttf/Xolonium-Bold.ttf」を適用する。
- 同じく「DynamicFont」リソースの「Settings」>「Size」プロパティを 40 にする。
- 同じく「DynamicFont」リソースの「Settings」>「Outline Size」プロパティを 4 にする。
- 少し戻って、「Theme Overrides」>「Colors」>「Font Color」を有効にして、色は #000000 (黒) のままにしておく。
- 2D ワークスペースにて、ツールバーの「レイアウト」から「中央」を選択する。
スクリプトをアタッチしてコーディングする
上下矢印キーでプログレスバーを更新させる
ではキーボードの上下矢印キーでプログレスバーの値が変化するようにスクリプトをコーディングしていこう。「TextureProgress」ノードの「Value」プロパティの値を変化させることで、「Texture」>「Progress」プロパティの表示範囲も連動してくれる。
- 「CircularProgressBar」ルートノードにスクリプトをアタッチする。ファイル名を「Progress.gd」としてファイルパスは「res://Progress.gd」とする。
- エディタが開いたら、以下のように編集する。
###Progress.gd###
extends Control
# TextureProgressノードの参照
onready var progress_bar = $TextureProgress
# Labelノードの参照
onready var label = $Label
func _ready():
# TextureProgressノードのvalueプロパティを0にリセットする
progress_bar.value = 0
func _process(delta):
# 入力操作を処理するメソッドを呼び出す
get_input()
# LabelノードのTextプロパティを更新するメソッドを呼び出す
update_label()
# 入力操作を処理するメソッド
func get_input():
# もし上矢印キーを押したら
if Input.is_action_pressed("ui_up"):
# TextureProgressノードのValueプロパティの値に1をプラス
progress_bar.value += 1
# もし下矢印キーを押したら
if Input.is_action_pressed("ui_down"):
# TextureProgressノードのValueプロパティの値から1をマイナス
progress_bar.value -= 1
# Labelノードのtextプロパティを更新するメソッド
func update_label():
# TextureProgressノードのValueプロパティの値に%をつけて表示する
label.text = str(progress_bar.value) + "%"
ではプロジェクトを実行して、上下矢印キーでプログレスバーの値を変化させてみよう。初めてプロジェクトを実行する場合は、メインシーンの選択を促すダイアログにて、現在のシーンをメインシーンとして設定すればOKだ。
プログレスバーの値に連動して色を変化させる
モノクロだと味気ないので、プログレスバーの色も変化させてみよう。今度は、プログレスバーの値の変化に合わせて、徐々にプログレスバーの色も変化させたい。「TextureProgress」ノードの「Value」プロパティの値の更新をより細かくするために「Step」プロパティの値を小さくしておこう。今回は 0.1 に設定する。
スクリプトを以下のように編集する。
###Progress.gd###
extends Control
# TextureProgressノードのtint_progressプロパティ(Colorクラス)の...
# h, s, vプロパティの始まりと終わりの値を指定するプロパティ(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()
# 追加:色相を更新するメソッドを呼び出す
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) + "%"
# 追加:色相を更新するメソッド
func update_color():
# Valueプロパティの値がminからmaxへ変化するのに合わせてプログレスバーの色相を変化させる
progress_bar.tint_progress.h = range_lerp(progress_bar.value, progress_bar.min_value, progress_bar.max_value, h_start, h_end)
# Valueプロパティの値がminからmaxへ変化するのに合わせてプログレスバーの彩度を変化させる
progress_bar.tint_progress.s = range_lerp(progress_bar.value, progress_bar.min_value, progress_bar.max_value, s_start, s_end)
# Valueプロパティの値がminからmaxへ変化するのに合わせてプログレスバーの明度を変化させる
progress_bar.tint_progress.v = range_lerp(progress_bar.value, progress_bar.min_value, progress_bar.max_value, v_start, v_end)
それでは改めてプロジェクトを実行してみよう。
色の変化があると美しいような気はするが、あくまでゲームに合わせたデザインを心掛けたい。
さまざまな形状のプログレスバー
ここまで実装してみてお気づきかもしれないが、プログレスバーはその形状となる画像リソースさえあれば、割と応用が効くのだ。
ここまでに作成した「CircularProgressBar.tscn」を複製して、少しプロパティを変更するだけで、色々なパターンのプログレスバーを比較的簡単に作ることができる。いくつかのサンプルを用意したのでご覧いただきたい。
ハート型のプログレスバー
ルートノードの「Script Variables」の各プロパティ。色相は紫から赤へ。彩度と明度は最初から高め。
「TextureProgress」ノードの「Fill Mode」プロパティ。下から上に進行。
「TextureProgress」ノードの「Textures」>「Under」/「Progress」プロパティ。ハートのテクスチャを適用。
シーンを実行。
ドクロ型のプログレスバー
ルートノードの「Script Variables」の各プロパティ。色相は緑から青へ。彩度は低めに抑える。
「TextureProgress」ノードの「Fill Mode」プロパティ。中央から上下両方向へ。
「TextureProgress」ノードの「Textures」>「Under」/「Progress」プロパティ。ドクロ型のテクスチャを適用。
シーンを実行。
フラスコのプログレスバー
このサンプルでは「Progress.gd」スクリプトを少し編集する。
###Progress.gd###
# 追加: バーの限界値(初期値はmax_valueに合わせて100)
export (float) var value_limit = 100
# 入力操作処理のメソッド
func get_input():
if Input.is_action_pressed("ui_up"):
progress_bar.value += 1
# 追加:バーの限界値までしかバーを進行させない
progress_bar.value = min(progress_bar.value, value_limit)
if Input.is_action_pressed("ui_down"):
progress_bar.value -= 1
# Labelノードのtextプロパティを更新するメソッド
func update_label():
# 追加:Labelの%をバーの限界値を1として計算
var actual_value = floor(progress_bar.value / value_limit * 100)
label.text = str(actual_value) + "%"
ルートノードの「Script Variables」の各プロパティ。ここで新たに追加したプロパティ「Value Limit」の値を 72.5 に変更している。これがちょうどこのあと適用するフラスコのテクスチャ画像に描かれている一番上の目盛りに合う値だ。
「TextureProgress」ノードの「Fill Mode」プロパティ。下から上へ。
「TextureProgress」ノードの「Textures」>「Under」/「Progress」プロパティ。フラスコのテクスチャを適用。
シーンを実行。上記の調整で、フラスコのテクスチャの一番上の目盛りでバーの進行が止まる。
脳みそのプログレスバー
ルートノードの「Script Variables」の各プロパティ。
「TextureProgress」ノードの「Fill Mode」プロパティ。
「TextureProgress」ノードの「Textures」>「Under」/「Progress」プロパティ。
「TextureProgress」ノードの「Radial Fill」>「Fill Degrees」を180にして、進行バーの展開できる角度を最大 180° とした。進行バーの回転の中心を脳みそのテクスチャのすぐ下までずらすために「Center Offset」の y の値を 130 とした。
シーンを実行。
ここまでに作ったものを1つのシーンにまとめてみる。
メインシーンの設定を変更してプロジェクトを実行するとこんな感じだ。
おわりに
今回は円形プログレスバーやその他の形状のプログレスバーの作成方法について紹介した。ポイントは以下の通りだ。
- プログレスバーの形状を決めるのはテクスチャ用の画像リソース。
- 形状に合わせて「TextureProgress」ノードの「Fill Mode」プロパティでバーの進行方向を設定する。
- スクリプトで「TextureProgress」ノードの「Value」プロパティの値を変化させることで、進行バーも連動させられる。
- スクリプトで「TextureProgress」ノードの「Tint」>「Progress」プロパティの色を変化させることで、バーの進行状況に合わせて色を変化させられる。
参考
- YouTube: Godot Circle Progress Bar Chart
- YouTube: Creating a circular meter using a single Godot Control Node
UPDATE
2022/08/06 Header の構成とサイズを若干修正