ロバメモ - 素人のUnity覚書と奮闘記

素人のUnity覚書と奮闘記

float値の比較は危険だった

二つの座標を比較した時にはまったのでメモ。

問題点

そのままfloat同士で比較

Ray飛ばしてヒットしたオブジェクトの座標と自身の座標を比較したくて書いたコード。
これをy=-4.8のオブジェクトとy=-4.2のオブジェクトの両方にアタッチしてある。

Debug.Log(hit.transform.position.y + " : " + transform.position.y);
if (hit.transform.position.y <= transform.position.y)
  Debug.Log(hit.transform.position.y + " ok"); 

これをforeach内に書いて実行したところ
f:id:nico-taniku:20190425160523p:plain:w300
なぜ、この後に -4.2 ok が表示されないのだ!

10掛けて切り捨ててみる(float型のまま)

不動小数点とやらがまずいのか?と考えてこんなことをしてみたが・・・

Debug.Log(Mathf.Floor(transform.position.y * 10) + " : " + transform.position.y); 

f:id:nico-taniku:20190425161021p:plain:w300
-4.2f が 10倍して切り捨てたら -43 になってるや〜ん!

それをintにしてみる

そうだ!floatをやめてしまえ!ということで、

(int)Mathf.Floor(hit.transform.position.y * 10)

コードは割愛バージョン。笑
Mathf.Floor()は要らんようなと思いつつ、こんな感じで書いてみたら
f:id:nico-taniku:20190425163225p:plain:w300
やっぱり、アカンのか〜い!

文字列しにしてからintにしてみる

だったら、文字列にしたろうやないかい!ということで・・・

int.Parse((hit.transform.position.y * 10).ToString()) 

f:id:nico-taniku:20190425164157p:plain:w300

なんや、合ってるかわからんけど、出来たっぽい〜♪

エラー対策

小数点がつくと数値にするときにエラーが出るのでMathf.Floor()をつけたんだけど、それだとまた不動小数点とやらが狂わせてきたので、ToString()じゃなくてstring.Format()を使うことにした。

int.Parse(string.Format("{0:0#}", hit.transform.position.y * 10))

結論

floatを比較するときは、文字列にしてからintに直したら良い感じ♪

int.Parse(string.Format("{0:0#}", float値 * 10))

{0:#}だと値が0のときにエラーが出たので{0:0#}にした。

等しいかどうかを調べる

等しいかどうかを調べるには、Mathf関数を使うといいみたい。

public static function Approximately(a: float, b: float): bool;

docs.unity3d.com

以上です。