【Unity】背景色を時間変化させる

いろいろなタイマーと言う事で、
4種類のタイマーを作ってみました。

・デジタル
・背景色変化
・アクション
・プログレスバー

前回デジタル表示に触れたので、
今回は、背景色変化について記事にします。

設定はandroidで行っています。
CanvasとImageを追加して、このImageを背景とします。

60秒でGreen→Yellow→Redと変化させていくので、
Imageの色をGreenにセットするのですが、
Timer③.jpg
最初は、画像の赤枠の部分がRGB0-255になっていると思います。

Greenから色変化させる場合、RGBだと色変化させるのに
かなりの手数が必要になります。

実際にバーを弄りながら色変化をさせると
バーの操作が複雑なのが分かります。

そこで、
Timer④.jpg
RGB色空間からHSV色空間に変更します。

RGBは、皆さんご存じ三原色です。
HSVは、色相、彩度、明度で表す色空間です。

HSVに切り替えると
Timer⑤.jpg
H(色相)部分がGreenからRedまで見えています。

この部分を操作すると、Green→Yellow→Redの色変化ができそうです。

難点は、Yellowの部分が短いのと
このまま、HバーをYellowに合わせるとわかるのですが、
Timer⑥.jpg
明度が低いので、黄土色と言うかうんこ色……

これでは見た目が残念なんで、明度も弄っていきます。
だいたい明度90くらいで、綺麗な黄色になります。(*_*)ゝ目がイタイ

あとは、Redまで色相を動かせば完成するかと。

ここで、注意点があります。
Timer⑦.jpg
色相と彩度・明度では、バーのMax値が違います。

更に、バーを移動させるスクリプトでは、
バーの指定範囲は、0~1 となります。
色相なら1で360となります。
彩度・明度なら1で100。

なので移動量の計算は、(移動させる量/バーのMax値)にする必要があります。

処理としては、
・1秒毎に色相、明度を変化させていく
・通常色(Green)を長めにして、終盤でYellow→Redに移行
・Yellow帯が短いので、一時停止
・明度は60秒間で100に上げる

HSVの初期値
・H 108
・S 100
・V 60

この辺を考えながらスクリプトを組んでみたいと思います。

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

public class TimerManager : MonoBehaviour
{
//タイマー用変数
public float LimitTime; //タイマーの設定時間
private bool counting;          //タイマー稼働フラグ
private float Elapsedtime; //1秒を読み取る変数

//背景の色変化用変数
public GameObject ImageBack; //背景オブジェクト
private Image imageback; //背景のImageコンポーネント
//HSV操作用変数
private float Hue = 0.3f; //色相の初期数値
private float GreenBand = 0.0033f; //背景グリーンの色相減少
private float RedBand = 0.015f; //背景レッドの色相減少
private float Value = 0.6f; //明度の初期値
private float DecV = 0.0066f; //明度の減少値

// Start is called before the first frame update
void Start()
{
//Imageコンポーネント取得
imageback = ImageBack.GetComponent<Image>();
}

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

Imageを使うので、using UnityEngine.UI;を宣言。

HSV操作用変数について説明します。

色の変化は、1秒毎に発生させたいので、秒単位での変化量を計算しました。

Hueは、色相の初期値を設定 108/360で計算

GreenBandは、通常時の減算値 40秒間で色相 108→60へ
計算は、(108-60)/40秒/360=0.0033

RedBandは、残り10秒でRedに減算 60→5へ
計算は、 (60-5)/10秒/360=0.015

Valueは、明度の初期値 60/100で計算

DecVは、60秒間で 60→100に加算するので、
計算は、(100-60)/60秒/100=0.0066

タイマー部分と色変化の処理を

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

//1秒毎の処理呼び出し
if (Elapsedtime >= 1)
{
BackColor();
Elapsedtime -= 1.0f;
}

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

//背景のカラーを変化させる
void BackColor()
{
float hue = Hue;
float min = 0;
float max = 0.3f;

//色相の減算
//開始40秒間はグリーンの変化
if (LimitTime >= 20)
{
hue = Hue - GreenBand;
min = 0.166f;
}
//残り10秒でレッドに移行
if (LimitTime <= 10)
{
hue = Hue - RedBand;
min = 0.0138f;
}
Hue = Mathf.Clamp(hue, min, max);

//明度の加算
float value = Value + DecV;
Value = Mathf.Clamp(value, 0.6f, 1.0f);

//HSVの指定
imageback.color = Color.HSVToRGB(Hue, 1.0f, Value);
}

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

タイマー部分は前回と同じでLimitTimeを60秒に設定します。
今回は、1秒毎に色の処理を行うので、Elapsedtimeを設定して、
LimitTimeは、deltaTimeを減算、Elapsedtimeは、deltaTimeを加算します。

Elapsedtimeが1以上になれば、処理を呼び出し、
Elapsedtimeから1を引きます。

deltaTimeの加算は、小数点以下の端数がでます。
Elapsedtimeを0にリセットすると誤差が大きくなるので、1を減算しています。

カラー変化の処理ですが、
LimitTimeから開始40秒間は、GreenBandを使って色相減算します。
40秒から50秒までは、色相停止。
残り10秒でRedBandを使って色相減算します。

計算した値を、Mathf.Clampで指定範囲内の値に修正して、
HSVコマンドに代入します。

これは、バーの移動量を定数にしたので、誤差で下がり過ぎるのを防ぐためです。
別に無くても問題ないかと思います。

HSVの色指定には、HSVToRGBコマンドを使います。
HSV指定の色空間をRGB色空間にUnityが変換して設定できるそうです。

ざっくりとしてますが、以上がカラー変化のタイマーとなります。


今回は60秒固定のタイマーなので、変化量の数値などは固定していましたが、
タイマー時間を変化させたい場合は、変化量の計算をStartメソッドに組み込んで、
対応させれば、タイマー時間の数値を変える事も可能かと思います。

色変化させたい時などに応用して頂ければ幸いかと思います。

ま、あまり役には立たないかもしれませんが…(^_^;)\('_' ) オイオイ...

今回はこのへんで…
(^^)/~~デハデハ



この記事へのコメント