2017-09-23 5 views
0

私は浮動小数点数を使って、プレイヤーがゲームを終了する時間(秒)を計算して表示しています。Unity3dのタイマーとして大きい浮動小数点値を使用する

私のゲームでは時々速くなるので、時間の値を大きくする必要があります。

は、ここに私の問題だ:私はアップデートで次のコードを使用します

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

ゲーム開始時には、残り時間値(秒で年間約32万円)本当に高い数値に設定されています。

時間の低下率はゲームによって異なるため、time.deltaTimeのフロートを使用しています。

Unityはこの大きな初期値を3.2E + 07として保存します。 すぐに、私のcounter.textは正常に機能しません。次の科学的表記の値が現れるまで待つだけです。だから、タイマーのテキストが詰まっているように見えますが、バックでは実際にはまだカウントダウンしています。私はここで理にかなっていると思います。疑いを避けるために、カウンターディスプレイは100万以下の値で正常に動作します。

この問題を解決するにはどうすればよいですか? timeleft.ToStringを変換して正しい値を表示するにはどうすればよいですか?

以下のコメントによれば、誰かが代わりに小数点の使用を提案しました。それは浮動小数点を必要とするので、deltaTimeでは動作しません。または、小数点の使用方法や使い方を誤解しています。

新しいintを作成してfloatでMathf.RoundToIntを使用しようとしましたが、それは機能しません。タイマーは大きな値にとどまっています。

+1

floatの代わりに[decimal](https://stackoverflow.com/q/618535/578411)を使用しますか? – rene

+0

私は同じシナリオを試みましたが、私は自分のシーンで値をよく見ることができます。しかし、検査官には1e + 07と書かれています。@reneが言ったように浮動小数点を10進数に変更しました。それはうまくいく。 – Thalthanas

+0

[科学的表記なしの2倍から文字列への変換]の可能な複製(https://stackoverflow.com/questions/1546113/double-to-string-conversion-without-scientific-notation) – FCin

答えて

1

ここでは、浮動小数点演算は数字に関する普通の人間の直感に従わないということです。

あなたが書く:これは間違ってい

Unity stores this big initial value as 3.2E+07. As soon as that happens, my counter.text doesn't work properly anymore, as that just waits until the next scientific notation value comes up. So it looks like the timer text is stuck, while in the back it is in fact still counting down.

:それは、数自体Time.deltaTimeの値が小さいために変更されていない変更していないだけでテキストではありません。問題は、値が大きくなるとfloatの精度が低下することです。さらに、基礎となる記憶形式がbinary floating-pointであるため、次に大きい番号と次に小さい番号との間の「ギャップ」を直感的に理解することは困難である。

次のコードで、この自分自身をテストすることができます。

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に等しいためです。

解決策は、コメントで指摘されているように、基本10形式を使用し、人間の直感によく似たdecimalを使用することです。これは正しくカウントダウンされます。

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

それを試しても、Unityが私にこのエラーを与えてくれます。暗黙的に 'decimal '型を' float'に変換できません。明示的な変換が存在する(キャストがありませんか?) – Killbert

+1

ああ、私の悪い、エラーはどこか他の人から来た。あなたのソリューションは魅力的に機能します。人間の直感の教訓をありがとう;-) – Killbert

関連する問題