Search Unity

script PlayableGraph to play timline

Discussion in 'Timeline' started by wang37921, Mar 8, 2019.

  1. wang37921

    wang37921

    Joined:
    Aug 1, 2014
    Posts:
    102
    While I use PlayableGraph play the timline, seems the second AnimationTrack no working.
    My timeline asset looks like this:
    upload_2019-3-8_15-15-34.png
    the first animation track is animation idle->walk->idle
    second animation track is the position record.
    while i use PlayableDirector Component, it is all right, play animation and move.
    But, when i remove the PlayableDirector Component and add a script Component:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Animations;
    3. using UnityEngine.Playables;
    4. using UnityEngine.Timeline;
    5.  
    6. public class NewBehaviourScript : MonoBehaviour
    7. {
    8.     [SerializeField]
    9.     TimelineAsset _timeline;
    10.  
    11.     PlayableGraph _graph;
    12.  
    13.     // Start is called before the first frame update
    14.     void Start()
    15.     {
    16.  
    17.         _graph = PlayableGraph.Create("CuteCharacter");
    18.         var output = AnimationPlayableOutput.Create(_graph, "Animation", GetComponent<Animator>());
    19.         var playable = _timeline.CreatePlayable(_graph, gameObject);
    20.         output.SetSourcePlayable(playable);
    21.         _graph.Play();
    22.     }
    23.  
    24.     private void OnDestroy()
    25.     {
    26.         _graph.Destroy();
    27.     }
    28. }
    29.  
    only the animation play, no moving.

    And, I found:
    upload_2019-3-8_15-22-52.png
    if using Playable Director, and lose the second AnimationTrack's Bindings, it is same as my script. Only Animation playing, no moving.

    So,
    Did I missing something setting in my script. I want script PlayableGraph to play the timeline, not through PlayableDirector Component.

    I have tried, if i switch the AnimationTrack's order:
    upload_2019-3-8_15-44-51.png
    and use the script component, now the animation not play, but it moving.

    So, I thought _timeline.CreatePlayable(_graph, gameObject), maybe only set the first AnimationTrack's Binding GameObject.
     
    Last edited: Mar 8, 2019
  2. wang37921

    wang37921

    Joined:
    Aug 1, 2014
    Posts:
    102
  3. julienb

    julienb

    Unity Technologies

    Joined:
    Sep 9, 2016
    Posts:
    177
    When building a playable graph from a timeline asset, each track adds a playable output to the graph. A playable output communicates with the outside world (your scene) to apply the graph's changes. In the case of Animation tracks, an output of type AnimationPlayableOutput is added. It needs an animator to write the graph's animation changes; ''someone'' needs to tell the output ''where'' to write the changes.

    When you use a PlayableDirector component, all this is done automatically; in your second screenshot, the Bindings section of the component tells you where each track will apply its changes.

    If you do not use the PlayableDirector, you will have to do this work yourself. You will need to check the graph's outputs and set the animator component on those outputs. On the PlayableGraph, you can use the following methods to get the outputs:
    GetOutputCount()
    GetOutputCountByType<T>()
    GetOuput(index)
    GetOutputByType<T>(index)


    Once you get an output, you can cast it to a AnimationPlayableOutput and set its target animator. I updated you script to do what you want:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Animations;
    3. using UnityEngine.Playables;
    4. using UnityEngine.Timeline;
    5.  
    6. public class NewBehaviourScript : MonoBehaviour
    7. {
    8.     [SerializeField] TimelineAsset _timeline;
    9.     [SerializeField] Animator _animator;
    10.  
    11.     PlayableGraph _graph;
    12.  
    13.     void Start()
    14.     {
    15.         _graph = PlayableGraph.Create("CuteCharacter");
    16.         _timeline.CreatePlayable(_graph, gameObject);
    17.      
    18.         //for each animation output, assign the animator component
    19.         var count = _graph.GetOutputCountByType<AnimationPlayableOutput>();
    20.         for (var i = 0; i < count; i++)
    21.         {
    22.             var output = (AnimationPlayableOutput)_graph.GetOutputByType<AnimationPlayableOutput>(i);
    23.             output.SetTarget(_animator);
    24.         }
    25.      
    26.         _graph.Play();
    27.     }
    28. }
    If you have multiple tracks which need a different animator component for each track, you will need to add logic to define which animator will be bound to a given track.
     
    Last edited: Mar 8, 2019
  4. wang37921

    wang37921

    Joined:
    Aug 1, 2014
    Posts:
    102
    thank you