Search Unity

Calling Instantiate on a TimelineAsset breaks all the child tracks

Discussion in 'Timeline' started by panta, Sep 12, 2018.

  1. panta

    panta

    Joined:
    Aug 10, 2012
    Posts:
    71
    Hi,

    We have several use-cases in our game where we want to be able to create an "instance" of a timeline asset at runtime, and then add additional tracks to that instance. Examples of this include
    1. Adding a "Input track" that displays all the input that a character has received from the controller
    2. Adding new animation tracks with overrides, so that we can have 1 timeline for a given animation (such as a hit react), and then sub in the correct animation for the character at runtime

    Since the TimelineAssets are ScriptableObjects, I tried calling
    Code (CSharp):
    1.  
    2. TimelineAsset timelineAsset = Instantiate<TimelineAsset>((TimelineAsset)director.playableAsset);
    3. timelineAsset.name = timelineAsset.name + "_" + Animator.gameObject.name;
    4. director.playableAsset = timelineAsset;
    5.  
    This seemed to allow me to create an instance of the timeline, but it destroys the original TimelineAsset. If I have a look at the changes that occur to the asset file after I call Instantiate, I see that all of the track parents have been set to the copy of the timeline:
    upload_2018-9-12_14-58-42.png

    Is there any way to create an instance of a TimelineAsset to play in a director without destroying the original asset?
     
  2. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    Just out of curiousity, if you reload the original timeline (unload/reload or restart Unity), does it correct itself? I believe it should, the parent tracks are fixed up on load - which is why Instantiate is breaking them.

    Timeline is a collection of scriptable objects (tracks, playableassets), so Instantiating the timeline will not copy the tracks, but reference them instead.

    We should provide a clone method for timelines. In the editor you can copy using the AssetDatabase, but obviously that doesn't work in a player.

    For your use case, what you are doing should work provided you don't modify the tracks, only add new ones. What you may need to do is have some editor only code that saves and restores the m_Parent serialized property on the tracks TimelineAsset.GetRootTracks() before/after instantiating, just to make sure the original doesn't actually get modified.

    I.e. I think having two timelines that reference the same tracks will work in the player, but not (always) in the editor window.

    Anyway, it's a very interesting use case.
     
  3. angusmf

    angusmf

    Joined:
    Jan 19, 2015
    Posts:
    261
    +1 for the ability to clone tracks!
     
    Arkade likes this.