Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Call method when a clip ends

Discussion in 'Timeline' started by luffyklose0822, Jul 24, 2022.

  1. luffyklose0822

    luffyklose0822

    Joined:
    Aug 3, 2018
    Posts:
    5
    Hello everyone, I'm working on customizing timeline clips in Unity, but I'm confused about some concepts now. I'm not sure what Playable, PlayableGraph, PlayableBehaviour and Playable Clip are. I want to call a function when one clip starts and ends, but I don't know which function I should call. Mine understanding of it is:
    1. The whole timeline is "Playable"
    2. this is the track as well as playable graph
    3. and this is the clip and playable behaviour
    I'm trying to control AI in the timeline, change NPC's state and make it move to somewhere when the clip starts and return to idle state when it ends. Why I make it a clip instead of a marker is that I want to adjust its speed by changing the clip's duration.

    And there are some similar functions in PlayableBehaviour, I'm not sure if there's a function I need. https://docs.unity3d.com/ScriptReference/Playables.PlayableBehaviour.html
     
  2. akent99

    akent99

    Joined:
    Jan 14, 2018
    Posts:
    588
    So many playable classes does make it confusing - I keep forgetting the exact details. I am not 100% sure, but I suspect you have to put markers (signals) on the tracks to get a function called at the start and end - I don't think there is a callback function for some reason. (But I could be wrong!)

    The way I generally remember it is clips are for the editor to use - all the details you can set in the editor when using the UI. Tracks also have a track asset that stores all the clips on disk (you have to tell it the clip type and binding type if binding is supported).

    When you run the playable, PlayableBehavior's do the actual work (the clip details get copied over into them). But you can blend between clips, so you need a mixer to combine them (if your tack supports it). I think PlayableGraph are the innards to coordinate creating all the playable and mixer - it does lifecycle management. But I will admit mixers still confuse me - there are some Good YT videos around.

    Hopefully someone can answer with more definitive answers, but the above was my understanding in case it helps.
     
  3. julienb

    julienb

    Unity Technologies

    Joined:
    Sep 9, 2016
    Posts:
    174
    Ciro's blog post gives a good overview of Timeline-related objects and concepts.

    PlayableBehaviour.OnBehaviourPlay is called when the clip starts and PlayableBehaviour.OnBehaviourPause is called when the clip ends.
     
    akent99 likes this.
  4. luffyklose0822

    luffyklose0822

    Joined:
    Aug 3, 2018
    Posts:
    5
    Thanks for replying. I know how to add markers, but I want to adjust the enemy's speed by only changing the playable's duration and that's why I choose a clip instead of two different markers.
     
  5. luffyklose0822

    luffyklose0822

    Joined:
    Aug 3, 2018
    Posts:
    5
    Thanks.
    I try to use OnBehaviourPlay and OnBehaviourPause to control but got a strange error.

    I use these codes to transfer playerData to my class.
    Code (CSharp):
    1. trackBinding = playerData as StateController;
    But the trackbinding equals null in OnBehaviourPlay and OnBehaviourPause. As a result I cannot call any method in StateController.
     
  6. julienb

    julienb

    Unity Technologies

    Joined:
    Sep 9, 2016
    Posts:
    174
    The track binding is not available in OnBehaviourPlay and OnBehaviourPause. You can access the binding during ProcessFrame (as playerData). ProcessFrame is called on each frame, for each active clip.

    edit: Added ProcessFrame docs link
     
  7. luffyklose0822

    luffyklose0822

    Joined:
    Aug 3, 2018
    Posts:
    5
    I have set trackbinding in ProcessFrame, I don't know why it's reset to null in OnBehaviourPlay and OnBehaviourPause.
     
  8. KuanMi

    KuanMi

    Joined:
    Feb 25, 2020
    Posts:
    41
    For some strange reason, we can't get the bound object like in ProcessFrame. Currently, you can only pass a reference to PlayableAsset in CreateTrackMixer of PlayableTrack, and then pass it to PlayableBehaviour in CreatePlayable.
    Code (CSharp):
    1.         public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount)
    2.         {
    3.             foreach (var clip in GetClips())
    4.             {
    5.                 ((clip.asset as CustomAsset)!).NotificationManager = go.GetComponent<PlayableDirector>().GetGenericBinding(this) as NotificationManager;
    6.             }
    7.  
    8.             var scriptPlayable = ScriptPlayable<CustomMixer>.Create(graph,inputCount);
    9.             return scriptPlayable;
    10.         }
    Code (CSharp):
    1.  
    2.         public override Playable CreatePlayable(PlayableGraph graph, GameObject owner)
    3.         {
    4.             var scriptPlayable = ScriptPlayable<CustomBehavior>.Create(graph,tmp);
    5.             scriptPlayable.GetBehaviour().notificationManager = NotificationManager;
    6.             return scriptPlayable;
    7.         }
     
  9. KuanMi

    KuanMi

    Joined:
    Feb 25, 2020
    Posts:
    41
    Could you please tell me why I can't get the bound object in OnBehaviourPlay and OnBehaviourPause? I really don't see what's the benefit of doing this. So that we have to use all kinds of weird ways to get this object.
     
    jvetulani likes this.
  10. jvetulani

    jvetulani

    Joined:
    Dec 20, 2016
    Posts:
    54
    Seconding this, I wanted to change an animator trigger from a timeline and without it it would just kept changing the trigger when used in ProcessFrame.