やりたい事
制限時間をつけるこでゲームを面白くしたい。
時間を管理する部品があれば便利だとおもう。
- 表示
- 残り秒数を表示したい
- ゲージ(画像)の長さを秒数に応じて変えたい
- 残り時間の操作
- 残り時間の増減できるようにしたい
- タイマーの開始・停止を制御できるようにしたい。
- タイマーが終了していることを確認したい
スクリプト
using UnityEngine;
using UnityEngine.UI;
namespace UdonTengoku
{
public class Timer : MonoBehaviour
{
/// <summary>
/// 残り時間を表示するText
/// </summary>
[SerializeField] Text timerText = default;
/// <summary>
/// 表示するテキストのフォーマット "F2" など
/// </summary>
[SerializeField] string format = default;
/// <summary>
/// タイマーのゲージ 残り時間に応じて fillAmount を操作
/// </summary>
[SerializeField] Image timerGauge = default;
/// <summary>
/// 残り時間の最大値(この時間からカウントダウン)
/// </summary>
[SerializeField] float maxTime = default;
/// <summary>
/// 経過時間
/// </summary>
float elapsedTime;
/// <summary>
/// 残り時間
/// </summary>
public float CurrentTime { get { return Mathf.Max(this.maxTime - this.elapsedTime, 0f); } }
/// <summary>
/// タイマーの停止状態
/// </summary>
public bool IsStopped { set; get; }
/// <summary>
/// タイマーが終了状態(0秒になると終了)
/// </summary>
public bool IsFinished { private set; get; }
void Start()
{
// タイマーの初期化
IsStopped = true;
IsFinished = false;
this.elapsedTime = 0f;
Display();
}
void Update()
{
if (IsStopped || IsFinished) return;
if (CurrentTime == 0f) IsFinished = true;
// 経過時間の加算
this.elapsedTime += Time.deltaTime;
Display();
}
/// <summary>
/// 残り時間の加算
/// </summary>
/// <param name="addTime">加算する秒数</param>
public void AddTime(float addTime)
{
if (IsStopped || IsFinished) return;
this.elapsedTime = Mathf.Clamp(this.elapsedTime - addTime, 0, this.maxTime);
}
/// <summary>
/// 残り時間の表示
/// </summary>
void Display()
{
this.timerText.text = CurrentTime.ToString(this.format);
this.timerGauge.fillAmount = CurrentTime / this.maxTime;
}
}
}
忘れがちなこと
timerGauge に指定するImageはImage Typeを Filledにするのを忘れないように。
これを忘れると、エラーがでず、ゲージも減らないので無駄に悩むことになる。
今後
IsFinished でタイマーが終了したかどうかを、ほかのクラスから取得できるけど
Update で監視し続ける必要があるので、改善したほうがよさそう。
Observerパターンを利用してタイマーの終了をゲームを管理するクラスに
伝えられるようにした方が、すっきりするかもしれない。