【Unity】プログレスバーを使ったタイマー

2021/1/16 Sliderを使ったロッドタイプの内容修正
2021/1/16 ブログの下に追記しました


暖冬の影響で温かい今日この頃ですが、
ケロはスキーヤーなので、悲しいシーズンを送っております。

近場のスキー場なら1時間くらいで行けるのですが、
いつも行くスキー場には、雪がありませぬ。(ToT )( ToT) ウルウル

わざわざ400㌔程離れた新潟まで足を延ばしております。(´`;)

愚痴っても仕方がないので、
本題の、プログレスバーを使ったタイマーについてまとめます。


サークルタイプ
白地の丸スプライトを一枚用意します。
Timer⑲.jpg
スライド部分に絵を入れたい場合は、もう一枚用意しておくといいかと。
インポートが終わったら、CircleProgressをまとめる空オブジェクトを用意します。

この中にImageを追加して、CircleBackとでもしておいて下さい。
このスプライトに白地の丸をアタッチします。
Timer⑳.jpg
Progressの部分より少し大きめにしておくといいかと思います。

今回は、Progressの部分を200×200にするので、
少し大きめの210×210にしました。

続いて、Imageを追加してProgressとして、CircleBackの上に設置します。
Timer㉒.jpg
スプライトに白地の丸、もしくは、別のスプライトをアタッチします。
白地の場合は、カラーを好きな物に変更します。

このImageがProgressの本体になるので、操作できるように設定を変更します。

まず、インスペクターのImageコンポーネントから
Timer㉓.jpg
画像タイプがシンプルになっているので、埋めてあるに変更します。
Timer㉕.jpg
radial360にすると円の動きになります。
FillOriginは動き出しの原点になります。今回は、上にしました。

後は、塗りつぶし量のバーをスライドすると円の動きで塗りつぶし量が変化します。
この部分をスクリプトから操作します。
Timer㉖.jpg
今回は、プログレスバーなので、円の中心部分を隠す為にCenterを被せて、
それっぽく仕上げてみました。

この辺りはお好みに合わせて下さい。
時間変化のスクリプトを作成します。
TimerManager

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class TimerManager : MonoBehaviour
{
//タイマー用変数
public float LimitTime; //タイマーの設定時間
private bool counting;          //タイマー稼働フラグ

//プログレスバー用変数
public GameObject CircleProgress; //円タイプのプログレスバー
private Image circle; //CircleProgressのImage取得用
private float PaintSpeed; //塗りつぶし速度用変数

// Start is called before the first frame update
void Start()
{
//CircleProgressのImageコンポーネント取得
circle = CircleProgress.GetComponent<Image>();
//塗りつぶし速度の設定
PaintSpeed = LimitTime;
}

// Update is called once per frame
void Update()
{
if (counting)
{
TimerCount();
}
}

//タイマー機能
void TimerCount()
{
//稼働時の経過時間
LimitTime -= Time.deltaTime;

ProgressMove();

//タイマーの停止
if (LimitTime <= 0)
{
counting = false;
}
}

//プログレスバー処理
void ProgressMove()
{
//経過時間から塗りつぶし量を計算
float amount = Time.deltaTime / PaintSpeed;

//塗つぶし量を代入する
circle.fillAmount += amount;
}

//タイマースタート
public void PushStart()
{
counting = true;
}

Imageコンポーネントを操作するので、using UnityEngine.UI;を宣言します。
タイマー部分とスタートボタンについては端折ります。
ちなみにタイマーは60秒設定です。

塗りつぶし量は、fillAmountです。
Unityを日本語化すると分かりにくいヽ(´~`;)ウーン

deltaTime毎にfillAmountの角度を代入していきます。

計算と言う程でもないのですが、
360°をタイマー設定時間で回すので、速度に直すと
360°/60秒が速度になります。

ただし、fillAmountは、0~1が範囲なので、1/60秒となります。

deltaTime毎の塗りつぶし量は、deltaTime×1/60秒となるので、
単純に60で割っています。

LimitTimeは、時間変動するので速度計算には使えないので、
StartでPaintSpeedに代入しておいて、これを元に計算しています。

Circleタイプは以上です。


Sliderを使ったロッドタイプ
Timer㉗.jpg
キャンバスにUI→Slider でSliderオブジェクトを追加します。
カメラマークに被ると見えないくらい小さいSliderが生成されます(;^_^A

Timer㉘.jpg
サイズ調整を行って、巾500×高さ80くらいで画像の大きさになります。

Sliderには、Background、FillArea、HandleSlideArea で構成されています。
ハンドル自体の操作を無くしたいので、HandleSlideAreaを削除します。

HandleSlideArea削除後にSliderのインスペクターを見ると
Timer㉙.jpg
赤矢印のエラーが出ますが無問題!

このままでは、ハンドルが無くなっただけで操作できてしまうので、
Interactableのチェックを外します。

これで手動操作ができなくなりました。

続いて、FillAreaの中のFillに切り替えます。
Timer㉚.jpg
インスペクターにImageコンポーネントがあるので色を変えます。
今回は青系にしておきます。

Sliderの左端に青い色ができたと思います。
この状態でSliderの操作をしてみます。
Timer㉛.jpg
Sliderのインスペクターを見るとSliderコンポーネントがあります。
下の方に行くとValueのつまみがあるので操作すると、オブジェクトの方も連動します。

このValueをスクリプトから操作してやるとプログレスバーの動きになるかと。
スクリプトはサークルタイプを流用します。

まず、
public GameObject CircleProgress; //円タイプのプログレスバー
private Image circle; //CircleProgressのImage取得用

を削除して、Slider取得用の変数に変更します。

時間経過等はサークルタイプと同じで問題なしです。

サークルタイプでfillamount(塗りつぶし量)を操作しましたが、
SliderはValueを操作するので、slider.valueに変更します。
これで、タイマーのように動かす事ができます。

//プログレスバー用変数
public Slider slider; //Sliderオブジェクト
private float PaintSpeed; //塗りつぶし速度用変数


 //プログレスバー処理
void ProgressMove()
{
//経過時間から移動量の計算
float amount = Time.deltaTime / PaintSpeed;

//スライダーの移動量を代入
slider.value += amount;
}

Slider変数にSlider本体をアタッチすれば動かせるようになります。

※この記事を作成した時には、分かってなかったのですが、
uGUIは、UIネームで取り込む事でGetComponentが要らなくなります。
なので、SliderオブジェクトもGameObjectでは無くて、Sliderで取得すると
そのままslider.valueのように指定する事ができます。



ただし、このままでは2つ残念な事があります。

・最初から左端に青い頭が見えている
Timer㉜.jpg

・ValueをMaxまで移動させると白いBackの色が残る
Timer㉝.jpg
なので、見た目の修正をします。

FillAreaを選択してインスペクターを見ると
Timer㉞.jpg
両端がそれぞれSliderオブジェクトより内側に設定されています。
これを左右0に変更します。

FillAreaをSliderの大きさに合わせる事でValueを1にすると
右端まで色が動くようになります。

この状態でValueを0にすると、左側は変わらず青い頭が出ています。
これを消すためにFillを選択します。
Timer㉟.jpg
幅が10に設定されているので、0に変更します。

これで端から端まで行くようになります。


最後にSliderを使った小ネタを少々
Timer㊱.jpg
Fillのカラーを緑に設定して

Timer㊲.jpg
Backgroundのカラーを赤にするとライフゲージになります。

スライダーは、Max値を設定できるので、
Timer㊳.jpg
ライフ100ならMaxValueを100にしてやると
Slide量の計算もしやすいかと思います。


以上がプログレスバーの内容となります。


時間変動だけでなく、体力ゲージやスキルゲージなんかにも応用ができるので、
使い所は多いかと思います。

何かの参考になれば幸いです。
それではこのへんで
( ^ 0 ^ )/~~~~see you again





追記

2021/1/16
分かりにくい部分を長らく放置してしまい
申し訳ないです(_ _(--;(_ _(--; pekopeko

またコメント下さったgamaさん、ありがとうございました。

修正して少しは、分かり易くなったと思うのですが、
分からない等あれば、気軽にコメントして頂けるとありがたいです。

Sliderのスクリプトの下に注意書きした、uGUIのGetComponent不要については、
新記事を作成予定しています。
更新した際は、目を通していただけると幸いでっす。

この記事へのコメント

  • gama

    スライダーは
    下記も変更が必要でした。
    private Slider slider; //CircleProgressのImage取得用

    slider = CircleProgrevoid Start(){
    slider = CircleProgress.GetComponent();
    }


    スライダーのUIがある事も知りませんでした。
    丁寧な記事は本当に助かります。
    ありがとうございます。

    2021年01月15日 15:34
  • gama

    ごめんなさい。
    訂正致します。

    private Slider slider;

    slider.value += amount;
    で動きました。
    2021年01月15日 15:48
  • kero

    コメントありがとうございます。
    確かにsliderのスクリプトは、説明不足でした。
    imageの操作とsliderでは、
    扱いが変わるのに触れてなかったですね_(^^;)ゞ

    Valueをイジれば動くので、
    サークルと同じ処理が使えると思って省略してました。

    また何かあればコメント頂けるとありがたいですm(_ _)m
    2021年01月15日 23:45