Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Bug Animation Clip Generation - Key Frame Time / Floating Point Error

Discussion in '2D' started by pikminscience, Jul 25, 2023.

  1. pikminscience

    pikminscience

    Joined:
    Mar 26, 2019
    Posts:
    36
    Hey,

    I'm using the Aseprite Importer package to generate animation clips. I've extended the package a fair bit to modify it to my workflow.
    One issue present in that package and something I can't seem to solve - floating point errors regarding frame timing.

    e.g. I have a 10fps animation (10 sample rate), I split each frame time entry to .1f

    Code (CSharp):
    1. var animationClip = new AnimationClip()
    2. {
    3. name = tag.name,
    4. frameRate = 10f
    5. };
    Code (CSharp):
    1. keyframe.time = frameId * .1f;
    2. frameId++;
    cry.png


    Kind of always expect this with floats but the thing that's a bit frustrating is - the animation won't hit the frame. If I simply go to the animation in the editor and drag it back and forth to the same keyframe, it all works!

    I can also just edit the serialised animation clip above but that's a lot of work :D

    Not sure why it's only happening at .9f (across all animations exported).

    Not sure if:
    A) Unity serialisation of the animation clip is not rounding at '1' time.
    B) Is there a function other than setting the time of the keyframe?

    Thought this fits 2D forum due to the issue mainly being with non-interpolated sprite states :D
     
  2. pikminscience

    pikminscience

    Joined:
    Mar 26, 2019
    Posts:
    36
    I think my brain has regressed and all computer science knowledge has been emptied out ;_;

    Code (CSharp):
    1. Double fraction = .1;
    2. keyframe.time = (float)(frameId * fraction);
    This works, I'm guessing the results are down to -> higher accuracy, casting up then converting vs multiplying an imprecise float prior to this.

    Would rather a better fix! Not trying to fix floating point errors :D trying to work out how Unity handles them for animation!

    cry1.png cry2.png
     
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,563
    Well even that perfect 0.1 isn't actually 0.1 (which is not precisely representable in base 2) so not sure you're seeing what you think you are seeing.

    What do you mean in your first post :

    Do you mean it simply won't drive the sprite for that frame of animation for that point in time??

    I just made a sprite animation, then hand-edited the .anim file to fiddle with the timing of the keyframes and it all worked correctly, changing it by adding 0.01, 0.001, 0.011, etc.

    If you're doing this yourself you shouldn't be testing floating point for equality: check for "was less last frame, now greater than or equal" and it will always work.

    Floating (float) point imprecision:

    Never test floating point (float) quantities for equality / inequality. Here's why:

    https://starmanta.gitbooks.io/unitytipsredux/content/floating-point.html

    https://forum.unity.com/threads/debug-log-2000-0f-000-1f-is-200.1153397/#post-7399994

    https://forum.unity.com/threads/why-doesnt-this-code-work.1120498/#post-7208431

    "Think of [floating point] as JPEG of numbers." - orionsyndrome on the Unity3D Forums
     
  4. pikminscience

    pikminscience

    Joined:
    Mar 26, 2019
    Posts:
    36
    Yup - sorry, it's a confusing post. I understand basically any representation of a floating point is going to hit inaccuracy. It's how Unity handles them in the animation I'm having issue with (and it seems very present all over the Aseprite Importer package).

    Here's a repro through gifs.
    SETUP:
    5 sprites - red, green, blue, black, white

    Working as expected (note curve times to right) -


    Added similar small inaccuracy I get when creating an animation clip programmatically (I've hand edited the 3rd frame time)
    Note green never switches to blue (third frame)-


    It's an issue you never get in the editor when you move keyframes about.

    It's not noticeable when you're sampling at a rate higher than the animation's intended fps:


    I get what's going on - the next sample is a greater time and it switches the sprite at this point.

    I guess with a fresh day to explain my problem clearer -

    Making animations with the API (or Aseprite Importer), I can't seem to get the same results as I do when I create animations in the editor.
    At some point the float I hand the keyframe.time gets serialised with a rounded(?) imprecision which causes the keyframes to not trigger as expected in the editor.
    Moving these keyframes in the editor fixes the issue :D (or hand manipulating them...or doing the float cast in my first post)