概要
用途にもよるが安易にfloatで時間の加算をするとどんどんおかしくなる。
実践
時間の計算(カウントダウン)
よく記事で見かける
Time.deltaTime
を使うのはいいとして
using UnityEngine;
using TMPro;
public class TimerCountDown : MonoBehaviour
{
[SerializeField] float m_CounterMax;
[SerializeField] float m_Counter;
[SerializeField] TextMeshProUGUI m_CounterText;
// Start is called before the first frame update
void Start()
{
m_Counter = m_CounterMax;
}
// Update is called once per frame
void Update()
{
m_Counter -= Time.deltaTime; // 減算
if(m_Counter < 0)
{
Debug.Log("終了。");
}
m_CounterText.text = ((int)m_Counter).ToString();
}
}
実行結果
経過時間(プレイ時間)を表示したい場合
同じように実装するのはNG
m_Counter += Time.deltaTime; // 加算
うまく動いているように見えるが
何十時間もプレイ時間をためておく場合にはうまく動かない
例えば20時間=72000秒経過していたとする。
全然おかしい、floatの仮想部23bitでは限界があるのでdoubleを使う必要がある。
時間経過のサンプルコード
using UnityEngine;
using TMPro;
public class TimerCountDown : MonoBehaviour
{
[SerializeField] double m_CounterMax;
[SerializeField] double m_Counter; // double
[SerializeField] TextMeshProUGUI m_CounterText;
// Start is called before the first frame update
void Start()
{
m_Counter = m_CounterMax;
}
// Update is called once per frame
void Update()
{
m_Counter += Time.deltaTime;
m_CounterText.text = m_Counter.ToString("F2");
}
}
期待通りの結果になる。
おわり
時間経過も10時間を超えないならfloatでいいかもしれないが、大体表記は99:99:99や999時間まで表すゲームが多い。
浮動小数点の落とし穴にはまらないようにしよう。
【unity】秒から時、分、秒を計算する。もよければ参考に
こちらのリポジトリーにサンプルのシーンを入れています。
コメント