繁体   English   中英

在Unity3d中使用较大的浮点值作为计时器

[英]Using a large float value as a timer in Unity3d

我使用浮动控件来计算和显示玩家完成游戏所需的时间(以秒为单位)。

在我的游戏中,时间有时会更快,因此剩余时间值需要变大。

这是我的问题:我在Update中使用以下代码:

  Update () {
            timeleft -= Time.deltaTime;
            Debug.Log (timeleft);
            counter.text = "Time Left = " +timeleft.ToString("F0");
    }

在游戏开始时,剩余时间值设置为非常高的值(3200万,大约一年,以秒为单位)。

在游戏中,时间下降的速率会有所不同,因此我使用的是带有time.deltaTime的浮点数。

Unity将这个较大的初始值存储为3.2E + 07。 一旦发生这种情况,我的counter.text就无法正常工作,因为它一直等到下一个科学计数法值出现为止。 因此,它看起来像是计时器文本被卡住了,而实际上在后面却仍在倒计时。 希望我在这里有意义。 为避免疑问:计数器显示适用于低于100万的值。

我该如何解决这个问题? 如何转换timeleft.ToString,使其显示正确的值?

根据下面的评论,有人建议使用小数代替。 这与deltaTime不兼容,因为它需要浮点数,或者我误解了在哪里以及如何使用小数。

我试图创建一个新的int并在浮点数上使用Mathf.RoundToInt,但这没有用:计时器停留在较大的值上。

这里的简短道义是浮点算术不符合人类对数字的一般直觉。

你写:

Unity将这个较大的初始值存储为3.2E + 07。 一旦发生这种情况,我的counter.text就无法正常工作,因为它一直等到下一个科学计数法值出现为止。 因此,它看起来像是计时器文本被卡住了,而实际上在后面却仍在倒计时。

这是不正确的:不只是文本没有变化,对于Time.deltaTime较小值, 数字本身也没有变化。 问题在于, float的精度会随着该值变大而降低。 而且,由于基础存储格式是二进制浮点数 ,因此很难理解第二大数字和第二小数字之间的“差距”。

您可以使用以下代码自己对此进行测试:

float f = 3.2e7f;
string s1 = f.ToString();
Console.WriteLine(s1);
string s2 = f.ToString("F0");
Console.WriteLine(s2);
string s3 = (f - 7).ToString("F0");

var f2 = f;
for (int i = 0; i < 3000000; i++)
{
    f2 = f2 - 1f;
}
var diff = f - f2;
Debug.Log(diff);
if (f2 == f) 
{
    Debug.Log("Floating point numbers are strange.");
}

尽管f2的值减少了300万次,但其值从未改变。 这是因为3.2e7f - 1f 等于 3.2e7f

如评论中所指出的,解决方案是使用decimal ,它使用以10为底的格式,并且更符合人类的直觉。 这将正确倒计时。

  decimal timeLeft = 3.2e7M;
  Update () {
            timeleft -= (decimal)Time.deltaTime;
            Debug.Log (timeleft);
            counter.text = "Time Left = " +timeleft.ToString("F0");
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM