Search Unity

Playable time never reaches 1 (0.9948893)

Discussion in 'Timeline' started by Freznosis, Mar 22, 2020.

  1. Freznosis

    Freznosis

    Joined:
    Jul 16, 2014
    Posts:
    298
    I have a custom playable. I calculate the current time and duration like this.

    Code (CSharp):
    1. public override void PrepareFrame(Playable playable, FrameData info)
    2.         {
    3.             clipTimeWeight = (float) playable.GetTime() / (float) playable.GetDuration();
    4.         }
    Simply dividing the current time by duration of the clip. This works fine for the most part, but the time never reaches 1. It usually stops at somewhere around 0.97, 0.98, 0.99, etc. And the same goes for trying to calculate the opposite end at zero. 0.001, 0.01, 0.0235, etc. The time is never exact. I also tried calculating it in ProcessFrame() and other methods but it's all the same. I can use a tolerance and do something like Mathf.Approximately but the resulting value sometimes will still fall out of the tolerance range. And even then, going from 0.97 to 1 with Mathf.Approximately results in a very abrupt change. I need it to be smooth.

    Does anyone know why this happens? And a better way to do this? For now I'm stuck using a workaround that involves info.weight but I don't want to be tied to the weight of the clip because my script depends on the time of the clip.
     
  2. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    The explanation here is two-fold

    1. Timeline is 'sampled' at arbitrary points, and those points depend on Time.deltaTime which can vary wildly. That means you cannot rely on it being sampled at exactly any point.

    2. PrepareFrame and ProcessFrame are called only while the clip is active. The clip is active in the range of [start,end) - meaning it is inclusive on the start of the clip and exclusive of the end. i.e. In your case the maximum clipTimeWeight will ever be is 0.99999999999. The reason for this is to guarantee adjacent clips are never both active at the same time.
     
    Freznosis likes this.
  3. Freznosis

    Freznosis

    Joined:
    Jul 16, 2014
    Posts:
    298
    Thank you for the info.

    I assumed this would be the case due to no value having the possibility to be absolute. However I would take a guess there is a proper way to do this? If I manually animate a float, it will always reach it's destination value. So I assume there's some internal [0-1] being calculated. Is it just not available externally? info.weight suffers from the same problem but is a lot more accurate.
     
  4. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    Animation tracks have extrapolate on by default, which in the case of 'infinite' mode means the curve is sampled for the entire track, and in the case of clips they are autoextended (by a hold or loop) to the next clip when there is a gap.

    The weight curves are two separate curves that are sampled with normalized time (based on the blend regions), in a similar manner to what you are using. They may appear more accurate because they are using an ease in/out curve by default, which has a flatter slope near the end points.
     
  5. dvuk89

    dvuk89

    Joined:
    May 11, 2020
    Posts:
    3
    Thanks for answers, I would just like to be sure. As it currently stands there is no way of making sure end state will be set correctly?
     
  6. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    Correct. The end state will be what was sampled last. If you have a signal on the last frame, I believe it will be fired.