Search Unity

How To: Play another timeline on playable director once a timeline has finished playing?

Discussion in 'Timeline' started by MadeFromPolygons, Jun 6, 2018.

  1. MadeFromPolygons

    MadeFromPolygons

    Joined:
    Oct 5, 2013
    Posts:
    3,983
    How do I start playing a timeline on a director once another has finished.

    Essentially I would like to play my "walk" timeline with a wrapmode of loop, once the "attack" timeline has played through once.

    Can be via code or any means, just need to figure out how to schedule like this
     
  2. MadeFromPolygons

    MadeFromPolygons

    Joined:
    Oct 5, 2013
    Posts:
    3,983
    I am starting to realise from my research that doing simple things like this, or having two timelines blend actually require a ton of workarounds.

    Can someone simply tell me if I should just abandon timeline for now for these use cases?

    Every time I try to use it for these use cases it seems to not hold up and noone can seem to tell me how to make these (what I thought would be relatively simple and common use cases) implementable or whether the system can do this :(
     
  3. Akitohisano

    Akitohisano

    Joined:
    Sep 11, 2017
    Posts:
    3
    Hey there, the solution could be very easy. You need to access to the PlayableDirector first and then change its timelineAsset property to another timeline.

    you can do something like this:

    Code (CSharp):
    1. director.playableAsset = newTimelineAsset;
    2. timeline = director.playableAsset as TimelineAsset;
    3.  
    4. // rebuild for runtime playing
    5. director.RebuildGraph();
    6. director.time = 0.0;
    7. director.Play();
    I'm actually making a framework for people to get access to Unity Timeline easily while during run-time. Please feel free to check here: https://github.com/JCx7/TSEiAVN/blob/master/Managers/TSEiATimelineManager.cs

    In the TSEiATimelineManager, the function "SwitchTo" is changing from one Timeline to another one.
     
  4. MadeFromPolygons

    MadeFromPolygons

    Joined:
    Oct 5, 2013
    Posts:
    3,983
    Thanks so much, I will definitely look at that over the weekend and provide some feedback!

    @Akitohisano I wanted to change the bindings for the incoming new timeline, what would I do?
     
  5. Akitohisano

    Akitohisano

    Joined:
    Sep 11, 2017
    Posts:
    3
    Hi, I'm so glad that it could help you. I'm going to make some sample scenes for people to understand.

    For your question, I hope you're talking about the bindings of a track in a timeline.
    In order to set, change bindings, you need to get access to the track first.

    1)
    If your new timeline is an empty timeline, then what you need to do is adding a track and make the bindings to a specific gameobject. But to add a track, Unity only provide a function "CreateTrack<T>" which cannot be directly used without track index. Here is something interesting, in the Unity Script API, there is only one function "T CreateTrack(Timeline.TrackAsset parent, string name)". However, if you go to Visual Studio and in your library there are two functions called "CreateTrack" in the same class TimelineAsset. So, the method I'm using is C# reflection.
    Code (CSharp):
    1. MethodInfo method = typeof(TimelineAsset).GetMethod("CreateTrack", new[] { typeof(TrackAsset), typeof(string) });
    2.             MethodInfo generic = method.MakeGenericMethod(trackType.GetType());
    3. TrackAsset newName = null;
    4. var track = generic.Invoke(timeline, new object[] { null, DEFAULT_ANIMATION_TRACK_NAME + bindings.name });
    5.                 newName = track as TrackAsset;
    6. director.SetGenericBinding(newName, bindings);
    You can check also in the TSEiATimelineManager, function AddTrack(TrackAsset trackType, GameObject bindings).
    The "director" is the PlayableDirector.

    2)
    if your new timeline is not empty, for instance you've added some tracks manually, then what you need to do would be quite easy. Just do:
    Code (CSharp):
    1. director.SetGenericBinding(tack, bindings);
    To get the "track", you need to use the index of that track.

    Good Luck!
     
    paulygons and MadeFromPolygons like this.