- Home /
Error: Input position is { NaN, NaN, NaN }.
Hello all,
I am getting this error only on rare occasions (so harder to figure out where). It shows up inside an Update loop, on this line:
transform.position = Utils.MoveTowardsPlayer( transform.position, activeMagnetZone, activeMagnetSpeed );
The MoveTowardsPlayer function is here:
public static Vector3 MoveTowardsPlayer( Vector3 from, float magnetZone, float magnetSmooth ) {
if( magnetZone == 0 || magnetSmooth == 0 ) return from;
Vector3 to = Dispatch.PlayerPos;
float distance = Vector3.Distance( from, to );
if( distance == 0 || distance > magnetZone ) return from;
// Above line originally was
// if( distance > magnetZone ) return from;
float smooth = magnetSmooth;
smooth *= (magnetZone-distance)/distance;
return Vector3.Lerp( from, to, Time.deltaTime * smooth );
// Alt method
// return Vector3.SmoothDamp( transform.position, magnetPos, ref magnetVelocity, magnetSmoothTime );
}
So, the only place I suspected could cause the error, was if distance is 0, so I am now checking for it as well - but I am not sure this is the reason, as I would have expected a "division by zero" error.
Can anyone help in figuring out which is the cause for the error?
I have found that getting the position (`transform.position`) In the Awake
function gives NaN values. It's really annoying and doesn't really make sense, but I had this error in a couple of my scripts and changing everything that has anything to do with transform from Awake
to Start
has solved that issue :)
Shouldn't 'from' be avoided as a variable name? It's a contextual keyword, right?
Answer by MibZ · Dec 05, 2012 at 08:00 PM
I'm not sure as to why you're getting non number values, but since your problem only occurs occasionally you won't have any problem skipping calculation for 1/30th of a second if you have bad values.
Since there is no way to actually declare a 'NaN' value, you have to check using float.isNaN();
if (!float.IsNaN(transform.position.x) && !float.IsNaN(transform.position.y) && !float.IsNaN(transform.position.z))
{
//Do stuff
}
Thanks. This can be helpful, but I am still wondering what is the source. At first I thought that Lerp sometimes returns NaN but I could not make it do so.
You could also add debug statements inside of the if statement logging the values of each variable you think might be causing it to help figure out where it comes from, that way you would only log the values when a NaN occurs
This check will of course work, but once you have a NaN value you won't get rid of it since he calculates the new position out of the old one. NaN will infect all calculations and the values will stay NaN.
Answer by Ichan · Nov 19, 2015 at 12:01 PM
Im a bit late but i replicated this nan issue. it occurred from adding a mesh collider to a model that already had a character controller and they collided with eachother so for anyone with this issue remove the mesh collider
CAN you explain better, i have the same error but in a dash obstacles game, when the a cube(theplayer) is in the corner of the ground(form by a rectangule) and it rotates at a certain angle, please help me, im using unity the last version, here is a post with the details. https://stackoverflow.com/questions/49122014/unity3d-how-can-i-get-the-solution-to-transform-position-assign-attempt-for-mai
You should probably post a detailed question
hey i have post the question with the details, here it is , can you explain your comment please https://answers.unity.com/questions/1477020/unity3d-how-can-i-get-the-solution-to-transformpos.html
Answer by Bunny83 · Dec 07, 2012 at 05:04 PM
Here, just put this right before your "return Lerp":
Debug.Log(
"MoveTowardsPlayer: \n"+
" from = " + from + "\n" +
" magnetZone = " + magnetZone + "\n" +
" magnetSmooth = " + magnetSmooth + "\n" +
" to = " + to +"\n" +
" distance = " + distance + "\n" +
" smooth = " + smooth + "\n"
);
The problem with NaN values is that they spread like cancer. Any calculation with a NaN value will result in NaN as well. Maybe the NaN comes from an external calculation which is not in your function but is transferred into it.
Ahm... thanks, but with this question I was looking for some insight as for what may cause a NaN value. The only two suspects I see in this function are the calculation of smooth (in case distance is 0, but then I expect a "division by zero" error, and not NaN) or the result from Lerp, which I am not sure is capable of returning NaN.
no, when you divide by 0 you get + or - infinity. You will get NaN when you divide 0 by 0 or sqrt(-1). Inside your function i don't see anything which directly causes a NaN, so i guess either magnetZone is 0 or the NaN is "generated" outside your function.
What does the debug.log return?
Btw, Lerp just does this:
public static float Lerp(float from, float to, float t)
{
return from + (to - from) * $$anonymous$$athf.Clamp01(t);
}
public static float Clamp01(float value)
{
if (value < 0f)
return 0f;
if (value > 1f)
return 1f;
return value;
}
public static float Distance(Vector3 a, Vector3 b)
{
Vector3 vector = new Vector3(a.x - b.x, a.y - b.y, a.z - b.z);
return $$anonymous$$athf.Sqrt(vector.x * vector.x + vector.y * vector.y + vector.z * vector.z);
}
All those functions can't produce NaN (unless you pass a NaN value in which case it will of course return NaN as i said above). Any floating point operation with a NaN value will result in NaN.
See this question for more details: http://answers.unity3d.com/questions/303470/is-isnan-not-isinfinity-.html
It's hard to say anything what causes your NaN value since we don't have your environment. That's why it would help to see where it is com$$anonymous$$g from. That's why i posted the Debug.Log
Lerp can indeed return NaN values; the calculations involve dividing one of the parameters by the other, if any of the values are 0 you could get a NaN return. You could add something like this before you call Lerp to find any 0 values and replace them with almost 0 values so you don't divide by 0 but you are only off by a thousandth of a unit or something of the like.
EDIT: I thought [CODE][/CODE] turned on code formatting, but I guess not in comments. Sorry bout that.
//Place this code inside the snippet you posted before you call Lerp ReplaceZeroes(from); ReplaceZeroes(to);
//Add this function to your script Vector3 ReplaceZeroes(Vector3 vectorToCheck) { if (vectorToCheck.x == 0) vectorToCheck.x = 0.0001f; if (vectorToCheck.y == 0) vectorToCheck.y = 0.0001f; if (vectorToCheck.z == 0) vectorToCheck.z = 0.0001f;
return floatToCheck;
}
Lerp can't produce NaN. I just posted the implementation of Lerp (taken from the original UnityEngine.dll) It can of course return NaN when you pass a NaN value in "from", "to" or "t".
It's best explained here:
http://en.wikipedia.org/wiki/NaN#Creation
Thanks both. So I think that may explain it. When I was getting the errors, I did not check
if( distance == 0 ) return from;
Since I added this condition (marked with a comment at the original post), I haven't seen the error yet.
So I am guessing it is safe to assume that if I check that distance != 0, and perhaps smooth != 0, I should probably be able to completely avoid NaN.
Your answer
Follow this Question
Related Questions
Smooth Camera transition (linear interpolation) Error 1 Answer
NaN exception when spawning soldiers 1 Answer
NaN error for Mathf.Asin 2 Answers
2 Scripting Errors I need help fixing!! 3 Answers