[Unity3D]關於NaN(Not a Number)的問題


原地址:[Unity3D]關於NaN(Not a Number)的問題

在游戲運行時,代碼若寫得不安全很容易出現NAN的異常。一旦NAN出現整個游戲不崩潰也壞死掉了,游戲上了則是要被直接打回來的節奏,更是一個開發及測試人員每人都要扣3000塊的大BUG。
 
一般表現為:
1.
transform.rotation assign attempt for "XXX" is not valid. Input rotation is {NaN, NaN, NaN, NaN}.
2.
Getting an error of rigidbody.force assign attempt for 'XXX' is not valid. Input position is { NaN, NaN, NaN }
3.
transform.localEulerAngles assign attempt for 'XXX' is not valid. Input localEulerAngles is { NaN, 0.000000, -0.000000 }
 
反正各種各樣類似了,有些還不直接報你錯,間接來搞你讓你找半天。
 
NAN就是字母意思了,NOT A NUMBER,一般是由於一個數除0造成的,所以若設計有除就要留心去確保安全。
 
一些簡單的計算可以讓人更好理解:
 
1 / 0 = NaN
1 + NaN = NaN
2 * NaN = NaN
 
可以說任何數涉及到與NaN的計算都會被直接同化,極其強悍的超能力啊!
 
又例如(C#):
float A = 1.0f;
float B = 2.0f;
float C = float.NaN; 
float result = A * B + C;//result則被同化成NaN了,因為C是NaN。
 
遇到NAN也可以拋出異常再處理,當然假設你就直接知道那里肯定會有NAN的了。 NaN不等於任何數字,也不等於它自身。所以你可以用NaN這個變量與自己對等判斷,若返回錯誤則是NaN,不過這些寫編譯器會提示你有傻逼代碼,你可以不理它。
 
例:X為NaN
 
bool b_NaN = ( X == X );
 
if(b_NaN)
Debug.Log("X is a number .");
else
Debug.Log("X is not a number !");
 
一般來說盡量避免這個NAN的出現。
 
在UNITY3D中,其更多可能出現在當Time.timescale為0的時候,因為游戲過程中,很多運算都直接關聯Time.deltaTime這個參數,一旦Time.timescale為0,那么Time.deltaTime的數值則為0.若不小心除了它又沒有發現,那么則是喜聞樂見的事情了,哈哈。
 
若想要實現暫停(用Time.timeScale的方式暫停)而某部分東西又可以動的話,可以考慮自己去計算一個幀時間間隔。當然這個有可能會第一幀的時間間隔特別長。所以需要你來初始化這個地方,或者直接計算丟掉大的f_DeltaTime值。
 
float f_LastFrameRealtime;
 
void Start()
{
f_LastFrameRealtime =  Time.realtimeSinceStartup ;
}
 
void Update()
{
float f_DeltaTime = Time.realtimeSinceStartup - f_LastFrameRealtime;
f_LastFrameRealtime =  Time.realtimeSinceStartup ;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM