2021/1/16 ブログの下に追記しました
暖冬の影響で温かい今日この頃ですが、
ケロはスキーヤーなので、悲しいシーズンを送っております。
近場のスキー場なら1時間くらいで行けるのですが、
いつも行くスキー場には、雪がありませぬ。(ToT )( ToT) ウルウル
わざわざ400㌔程離れた新潟まで足を延ばしております。(´`;)
愚痴っても仕方がないので、
本題の、プログレスバーを使ったタイマーについてまとめます。
サークルタイプ
白地の丸スプライトを一枚用意します。
スライド部分に絵を入れたい場合は、もう一枚用意しておくといいかと。
インポートが終わったら、CircleProgressをまとめる空オブジェクトを用意します。
この中にImageを追加して、CircleBackとでもしておいて下さい。
このスプライトに白地の丸をアタッチします。
Progressの部分より少し大きめにしておくといいかと思います。
今回は、Progressの部分を200×200にするので、
少し大きめの210×210にしました。
続いて、Imageを追加してProgressとして、CircleBackの上に設置します。
スプライトに白地の丸、もしくは、別のスプライトをアタッチします。
白地の場合は、カラーを好きな物に変更します。
このImageがProgressの本体になるので、操作できるように設定を変更します。
まず、インスペクターのImageコンポーネントから
画像タイプがシンプルになっているので、埋めてあるに変更します。
radial360にすると円の動きになります。
FillOriginは動き出しの原点になります。今回は、上にしました。
後は、塗りつぶし量のバーをスライドすると円の動きで塗りつぶし量が変化します。
この部分をスクリプトから操作します。
今回は、プログレスバーなので、円の中心部分を隠す為に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を使ったロッドタイプ
キャンバスにUI→Slider でSliderオブジェクトを追加します。
カメラマークに被ると見えないくらい小さいSliderが生成されます(;^_^A
サイズ調整を行って、巾500×高さ80くらいで画像の大きさになります。
Sliderには、Background、FillArea、HandleSlideArea で構成されています。
ハンドル自体の操作を無くしたいので、HandleSlideAreaを削除します。
HandleSlideArea削除後にSliderのインスペクターを見ると
赤矢印のエラーが出ますが無問題!
このままでは、ハンドルが無くなっただけで操作できてしまうので、
Interactableのチェックを外します。
これで手動操作ができなくなりました。
続いて、FillAreaの中のFillに切り替えます。
インスペクターにImageコンポーネントがあるので色を変えます。
今回は青系にしておきます。
Sliderの左端に青い色ができたと思います。
この状態でSliderの操作をしてみます。
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つ残念な事があります。
・最初から左端に青い頭が見えている
・ValueをMaxまで移動させると白いBackの色が残る
なので、見た目の修正をします。
FillAreaを選択してインスペクターを見ると
両端がそれぞれSliderオブジェクトより内側に設定されています。
これを左右0に変更します。
FillAreaをSliderの大きさに合わせる事でValueを1にすると
右端まで色が動くようになります。
この状態でValueを0にすると、左側は変わらず青い頭が出ています。
これを消すためにFillを選択します。
幅が10に設定されているので、0に変更します。
これで端から端まで行くようになります。
最後にSliderを使った小ネタを少々
Fillのカラーを緑に設定して
Backgroundのカラーを赤にするとライフゲージになります。
スライダーは、Max値を設定できるので、
ライフ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がある事も知りませんでした。
丁寧な記事は本当に助かります。
ありがとうございます。
gama
訂正致します。
private Slider slider;
と
slider.value += amount;
で動きました。
kero
確かにsliderのスクリプトは、説明不足でした。
imageの操作とsliderでは、
扱いが変わるのに触れてなかったですね_(^^;)ゞ
Valueをイジれば動くので、
サークルと同じ処理が使えると思って省略してました。
また何かあればコメント頂けるとありがたいですm(_ _)m