Search Unity

How to evaluate a PlayableGraph at a specific time?

Discussion in 'Timeline' started by PhilSA, Apr 2, 2018.

  1. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,926
    Here's what I want to do:
    • I have an animator with a single animation in its animatorController
    • I want to be able to tell it "go at time X and apply the state you'd have at that time"
    Here's how I try to do this currently:
    Code (CSharp):
    1.  
    2.     // Get the playableGraph of the Animator, and make it so that we have to manually update it
    3.     PlayableGraph PlayableGraph = Animator.playableGraph;
    4.     PlayableGraph.Stop();
    5.     PlayableGraph.SetTimeUpdateMode(DirectorUpdateMode.Manual);
    6.  
    7.     // Get the AnimationClipPlayable of the animation
    8.     // (I get it in a less ugly way in my real code. I promise!)
    9.     _clipPlayable = PlayableGraph.GetRootPlayable(0)
    10.         .GetInput(0)
    11.         .GetInput(0)
    12.         .GetInput(0)
    13.         .GetInput(0);
    14.    
    15.     // Set the time of the clip to some arbitrary time we'd want to sample
    16.     _clipPlayable.SetTime(15.875);
    17.  
    18.     Debug.Log(_clipPlayable.GetTime()); // This outputs 15.875
    19.  
    20.     // Evaluate, so that the pose at that time should be applied
    21.     PlayableGraph.Evaluate();
    22.  
    23.     Debug.Log(_clipPlayable.GetTime()); // This outputs 0
    24.  
    However, this doesn't work. The animated object remains at its initial position.
    What I've found is that if I try to Debug.Log(_clipPlayable.GetTime()) just before doing Evaluate(), the value is correct. But after Evaluate(), the "_clipPlayable.GetTime()" is back to 0.

    Is this normal? How can I accomplish what I want?
     
    Last edited: Apr 2, 2018
  2. AubreyH

    AubreyH

    Joined:
    May 17, 2018
    Posts:
    18
    I've been having a few issues with calling Evaluate(0f) (Which is synonymous with the default .Evaluate() ) on a playablegraph. If I do it even once, it seemingly refuses to be evaluated again. If I'm careful to not update it without a significant delta (and never negative deltas sadly :( ) I can keep it alive, but what it considers "zero" is seemingly a bit bigger than float.Epsilon.

    A strange day.
     
  3. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    I think the issue has to do with using the playableGraph on the animator, which has an animator controller playable that is also managing the time of the clips in the graph.
     
  4. zeotron

    zeotron

    Joined:
    Nov 30, 2018
    Posts:
    3
    I'm having a similar problem; only I am using an "AnimatorControllerPlayable" directly in a PlayableGraph. I have found that if you drive "PlayableGraph.Evaluate" with a non-zero delta time then it won't reset the time, but that seems like a little bit of a hack.

    I even tried "SetPropagateSetTime" (discussed here), but that doesn't seem to fix the problem either.

    It's been about a year with no real solution. I would like to know the proper way to manually drive a PlayableGraph that contains an "AnimatorControllerPlayable."

    Is there any way we can get a more technical answer to this question?
     
    Last edited: Aug 28, 2019
  5. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    What are you trying to accomplish? To me, this seems like expected behaviour, but I don't have full context of what you are trying to do.

    The animator controller resets the time of it's clips when necessary (e.g. when a new state starts). Evaluate(dt) advances the current state. The controller doesn't maintain the current time of all it's clips, so changing their time while the graph is running would have an effect, but could always get reset if a transition occurs.

    Is that the behaviour you are observing?
     
  6. f0ff886f

    f0ff886f

    Joined:
    Nov 1, 2015
    Posts:
    201
    I think I have a similar request to the original question.

    Old Animation clips had this nice function: clip.SampleAnimation(SomeObject, 15.48f); which would set the state of the object to exactly that timestamp.

    It'd be great to have a playableDirector.SampleTimeline(4f); or, if that would be too much for the whole graph, perhaps per track we could sample the track at some time?
     
  7. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    playableDirector.time = 4f;
    playableDirector.Evaluate();

    does exactly that for timeline. It does it by setting the time on the root node (the timeline playable), which configures the graph and all times of connected graphs based on that time.

    For other playable graphs it very much depends on the structure of the graph. Each node has it's own time, the graph itself doesn't have a global time by default.
     
    f0ff886f likes this.
  8. learner_CL

    learner_CL

    Joined:
    Dec 23, 2016
    Posts:
    6
    yes,if i try to play playable manually,it's work in editor,but in playtime,it will be override by animator.
     
  9. AseanT

    AseanT

    Joined:
    Jan 22, 2013
    Posts:
    1
    Right, you will need to use LateUpdate(), as the Animator occurs after Update()