Help us understand the problem. What is going on with this article?

Unity 制限時間を管理するクラスを作成する

やりたい事

制限時間をつけるこでゲームを面白くしたい。
時間を管理する部品があれば便利だとおもう。

  • 表示
    • 残り秒数を表示したい
    • ゲージ(画像)の長さを秒数に応じて変えたい
  • 残り時間の操作
    • 残り時間の増減できるようにしたい
    • タイマーの開始・停止を制御できるようにしたい。
  • タイマーが終了していることを確認したい

スクリプト

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にするのを忘れないように。
これを忘れると、エラーがでず、ゲージも減らないので無駄に悩むことになる。

コメント 2020-03-11 213619.png

今後

IsFinished でタイマーが終了したかどうかを、ほかのクラスから取得できるけど
Update で監視し続ける必要があるので、改善したほうがよさそう。
Observerパターンを利用してタイマーの終了をゲームを管理するクラスに
伝えられるようにした方が、すっきりするかもしれない。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away