I wrote a job to update values on entities based on an event struct which has the startTime
, endTime
, start
and end
fields.
I made a method which should return math.lerp(start, end, math.unlerp(startTime, endTime, currentTime))
. (The real method checks whether startTime == endTime
is true and uses 0 to avoid NaN errors.)
And yet, I came across NaN errors while updating transform positions for entities.
And while I tried to find out the cause, I noticed that the errors don’t always appear depending on what I write even though I did not change the logic, only added Debug.Log
s.
So, I made a test method to confirm my suspicions.
private readonly float GetEVV(TimedEvent @event)
{
#if DEBUG
Debug.Assert(!math.isnan(@event.startTime), $"{nameof(@event.startTime)} is nan");
Debug.Assert(!math.isnan(@event.endTime), $"{nameof(@event.endTime)} is nan");
Debug.Assert(!math.isnan(@event.start), $"{nameof(@event.start)} is nan");
Debug.Assert(!math.isnan(@event.end), $"{nameof(@event.end)} is nan");
#endif
float t = @event.startTime == @event.endTime
? 0
: (currentTime - @event.startTime) / (@event.endTime - @event.startTime);//math.unlerp(@event.startTime, @event.endTime, currentTime);
//float v = math.lerp(@event.start, @event.end, t);
float v = @event.start + t * (@event.end - @event.start);
#if DEBUG
if (math.isnan(v) || math.isnan(t))
{
if (math.isnan(v))
Debug.LogWarning($"{nameof(v)} is nan");
if (math.isnan(t))
Debug.LogWarning($"{nameof(t)} is nan");
#if false // log them
if (@event.startTime == @event.endTime)
{
Debug.Log($"{@event.start} + {t} * ({@event.end} - {@event.start})");
}
else
{
Debug.Log($"{@event.start} + (({currentTime} - {@event.startTime}) / ({@event.endTime} - {@event.startTime})) * ({@event.end} - {@event.start})");
}
#endif
}
#endif
return v;
}
And depending on whether I set the #if
to true
or false
on line 21, the value of v
and t
changes.
If it is false, both become NaN
which is strange since t
should become 0 if startTime
is equal to endTime
which is the only one possible case for it to become NaN
.
(place of removed image 1)
But if it is true, the value becomes 0 without having any NaN errors.
(place of removed image 2 and 3)
Also, displaying startTime
, endTime
, start
and end
to the console with Debug.Log
also has a similar effect. It also shows that all of the values are 0 which shouldn’t be the case. So, I attached VS’s debugger to unity and inspected the value with it.
(place of removed image 4)
And just like magic, suddenly, the values aren’t 0 any more.
There were more images here, but discussions didn’t let me use more than 1 attachment since I am a new user.
-
removed image 1: the value of the component is NaN
-
removed image 2: the console is clear, no warnings
-
removed image 3: the value of the component is 0
-
removed image 4: VS’s debugger shows the values under locals
startTime = -7.788249E-05
endTime = 4.590934E-41
start = -7.788127E-05
end = 4.590934E-41The values being the same is probably another bug which I’ll have to fix but the important part is that neither of these values are 0.
I am at my wit’s end here. What am I doing wrong?