Search Unity

Playable director doesn't properly remember exposed references from multiple timelines

Discussion in 'Timeline' started by RyanShen, Sep 24, 2018.

  1. RyanShen

    RyanShen

    Joined:
    Jan 19, 2017
    Posts:
    1
    Summery of problem:
    Exposed references could have same exposed name if the owner timeline is duplicated from another. The playable director, when assigned with these timelines, will treat those exposed references as the same one so that different assignment from different timelines aren't remembered.

    A simplified use case of ours:
    We have a playable director component on a prefab under which several "way point" game objects are attached. The transforms of those "way points" are assigned to TransformTweenClip in our timelines so that our character will move from one transform to another.
    The playable prefab hierarchy looks like this:
    PlayableDirector
    - Waypoint1
    - Waypoint2

    We have several timelines that control the character differently.
    Timeline 1 has one track that has a TransformTweenClip with start location Waypoint1
    Timeline 2 has one track that has a TransformTweenClip with start location Waypoint2

    We usually create new timelines by duplicating old ones because those timelines will be similar in terms of number and type of tracks. And we only need to reassign references and adjust timing of clips rather than having to create everything from scratch.

    Now the issue is that the exposed name of start location in Timeline1 and start location in Timeline2 are same.
    When exposed reference information is saved on the prefab (where playable director is), there will only be one key value entry for start location. If we save prefab when Timeline1 is assigned to playable director, this value points to Waypoint1 and later when we save prefab with Timeline2, the value is changed to Waypoint2's file ID and key stays the same.

    My questions:
    Q1: Is this an expected use of timeline or does it conflicts with the design paradigm?
    Q2: Am I supposed to use one playable director for each timeline?
    Q3: Is there a way to customize the system so we can achieve our goal?
    Q4: I think scene bindings are saved properly for multiple timelines because they use both track ID and timeline asset guid as key. Is there plan to extend such functionality to exposed references?

    Thank you!
     
  2. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    Q1: It is expected.
    Q2: No, it is perfectly valid to swap timelines on a playable director.
    Q3: Yes.
    Q4: Not really.

    The duplication of clips with exposed references keeping the same name is perhaps a bug. I can see use cases for both keeping it and renaming it on duplicate, so at the very least we should somehow try to address that.

    It is possible to change the name of exposed references via scripts, or with the debug inspector. They are meant to be a tag, so that you could share the tag across multiple clips/timelines if that is what works best for you.

    In your case, it sounds like you need a script which reassigns all control track names in a script. Here's a quick example for control tracks, that you should be able to make work with whichever clip types you need.

    Code (CSharp):
    1.    public static void CloneReferences(PlayableDirector director)
    2.     {
    3.         var timeline = director.playableAsset as TimelineAsset;
    4.         foreach (var controlTrack in timeline.GetOutputTracks().OfType<ControlTrack>())
    5.         {
    6.             foreach (var clip in controlTrack.GetClips())
    7.             {
    8.                 var controlAsset = clip.asset as ControlPlayableAsset;
    9.                 if (controlAsset != null)
    10.                 {
    11.                     bool isValid = false;
    12.                     var obj = director.GetReferenceValue(controlAsset.sourceGameObject.exposedName, out isValid);
    13.                     if (isValid)
    14.                     {
    15.                         controlAsset.sourceGameObject.exposedName = System.Guid.NewGuid().ToString();
    16.                         director.SetReferenceValue(controlAsset.sourceGameObject.exposedName, obj);
    17.                     }
    18.                 }
    19.             }
    20.         }
    21.     }
    22.