Search Unity

References to TimelineClips don't update start/end/duration information

Discussion in 'Timeline' started by hoperin, Feb 7, 2019.

  1. hoperin

    hoperin

    Joined:
    Feb 9, 2014
    Posts:
    52
    I have a system that generates timelines and clips of custom clip types that correspond to events, and I use the start/end times of the clips to jump around my timeline as needed.

    On the initial creation of the timeline and the clips, which is done via a script rather than manually, I save a reference of each TimelineClip in a dictionary (The Key's are identifying Strings, and the Values are the TimelineClips themselves.)

    When i want to jump to a certain point in the timeline I find the TimelineClip I want to go to and use TimelineClip.start to get the time I need to jump the playhead to.



    Code (CSharp):
    1. public void SetStartAndEndClipTime(TimelineClip currentClipAsset) {
    2.  
    3.         currentClipStart = currentClipAsset.start * 60f;
    4.         currentClipEnd = currentClipAsset.end * 60f;
    5.  
    6.         ....
    7.  
    8.         dir.time = currentClipStart / 60f;
    9.     }
    I just realised, however, that if I want to start moving the clips around on the timeline to give myself more space to work or whatever other reason, the TimelineClips stored in the dictionary do not return the new start/end/duration times. They always return the information that applied when they were added to the dictionary, initially.

    I'm wondering A) why this would be the case in the first place?

    and B) how can I store references to TimelineClips that will actually return the proper current start/end information of the clip?

    Thanks in advance!
     
  2. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    Right, we know this issue far too well :)

    Because timeline clips are a serialized class within the Track, and not UnityEngine.Objects themselves, holding references to them don't work after a serialization occurs. You can end up referring to an old copy.

    There are a few workarounds to this possible. One would be to store the track (which is a UnityEngine.Object) and the playableAsset (clip.asset) which is normally a unique Object,. When you need to look for a time, you can search the track for the clip with the given asset.

    Or, during the compile phases (OnCreatePlayable, CreateTrackMixer) cache the times you need from clips.

    I hope that helps. It can be a tricky problem to deal with in the serialization system. Serialized classes are fast, but lack permanence, Scriptable objects have permanence, but have overhead to using them.
     
    hoperin likes this.
  3. hoperin

    hoperin

    Joined:
    Feb 9, 2014
    Posts:
    52
    Ah, thanks for the clear reply! At least it's a known issue that has a clear workaround and not something weird that I brought on myself! I'm either going to try a GUI button for updating my dictionary by iterating through the track's clips, which means I don't have to change too much but do need to remember to hit the button after I've made changes, or go the playableAsset route you've suggested.