Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

SetDuration of playable asset

Discussion in 'Timeline' started by HeyBishop, Dec 9, 2020.

  1. HeyBishop

    HeyBishop

    Joined:
    Jun 22, 2017
    Posts:
    238
    I have a:
    • PlayableAsset, called DialogClip. It has a public string and an AudioClip.
    • TrackAsset, called DialogTrack.
    • PlayableBehaviour, called DialogBehaviour
    • PlayableBehaviour, called DialogMixer
    Because there is a public audioclip in DialogClip, I'm able to drag an audio clip right onto the timeline - which is awesome.

    However, the duration always defaults to 5 seconds. I would like the default duration to be the duration of the audio clip. I would have thought using PlayableExtensions.SetDuration(audioClip.length) would do the trick - but it doesn't.

    How do I set the duration of a clip?

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Playables;
    3.  
    4. public class DialogClip : PlayableAsset
    5. {
    6.     [TextArea(2, 10)]
    7.     public string captionText;
    8.     public AudioClip audioClip;
    9.  
    10.     public override Playable CreatePlayable(PlayableGraph graph, GameObject owner)
    11.     {
    12.         var playable = ScriptPlayable<DialogBehaviour>.Create(graph);
    13.        
    14.         DialogBehaviour dialogBehaviour = playable.GetBehaviour();
    15.  
    16.         dialogBehaviour.captionText = captionText;
    17.         dialogBehaviour.audioClip = audioClip;
    18.         playable.SetDuration(audioClip.length);  ///////// this seems to do nothing
    19.  
    20.         return playable;
    21.     }
    22. }
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Playables;
    3.  
    4. public class DialogBehaviour : PlayableBehaviour
    5. {
    6.     public string captionText;
    7.     public AudioClip audioClip;
    8. }
    9.  
    10.  

    Code (CSharp):
    1. using UnityEngine.Playables;
    2.  
    3. public class DialogMixer : PlayableBehaviour
    4. {
    5.     public override void ProcessFrame(Playable playable, FrameData info, object playerData)
    6.     {
    7.         ActorManager actor = playerData as ActorManager;
    8.  
    9.         string currentText = "";
    10.         float currentAlpha = 0f;
    11.  
    12.         if (!actor) { return; }
    13.  
    14.  
    15.  
    16.         int inputCount = playable.GetInputCount();
    17.         for (int i = 0; i < inputCount; i++)
    18.         {
    19.             float inputWeight = playable.GetInputWeight(i);
    20.  
    21.             if (inputWeight > 0f)
    22.             {
    23.                 ScriptPlayable<DialogBehaviour> inputPlayable = (ScriptPlayable<DialogBehaviour>)playable.GetInput(i);
    24.  
    25.                 DialogBehaviour dialog = inputPlayable.GetBehaviour();
    26.                 currentText = dialog.captionText;
    27.                 currentAlpha = inputWeight;
    28.             }
    29.         }
    30.  
    31.         actor.speechBubble.captionText.text = currentText;
    32.         actor.speechBubble.canvasGroup.alpha = currentAlpha;
    33.     }
    34. }

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Playables;
    3. using UnityEngine.Timeline;
    4.  
    5. [TrackBindingType(typeof(ActorManager))]
    6. [TrackClipType(typeof(DialogClip))]
    7. public class DialogTrack : TrackAsset
    8. {
    9.     public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount)
    10.     {
    11.         ScriptPlayable<DialogMixer> scriptPlayable = ScriptPlayable<DialogMixer>.Create(graph, inputCount);      
    12.  
    13.         return scriptPlayable;
    14.     }
    15. }
     
  2. DavidGeoffroy

    DavidGeoffroy

    Unity Technologies

    Joined:
    Sep 9, 2014
    Posts:
    542
    You need to set the duration of the PlayableAsset, not the duration of the Playable.

    Here would probably be the best place.
     
  3. HeyBishop

    HeyBishop

    Joined:
    Jun 22, 2017
    Posts:
    238
    Thank you for responding so quickly.

    I'm having troubles figuring out how to call OnCreateClip(Timeline.TimelineClip clip) on my DialogClip PlayableAsset.

    Where should that go?
     
  4. DavidGeoffroy

    DavidGeoffroy

    Unity Technologies

    Joined:
    Sep 9, 2014
    Posts:
    542
    You need to implement it on the TrackAsset, not on the clip itself. It should be called automatically when a TimelineClip is created on your track.

    From there, you can access both the container (TimelineClip) and the contents (PlayableAsset)
     
  5. DavidGeoffroy

    DavidGeoffroy

    Unity Technologies

    Joined:
    Sep 9, 2014
    Posts:
    542
    If what you want is for your PlayableAsset to always have the same duration as your AudioClip, you should override
    PlayableAsset.duration, and return the duration of your AudioClip.
     
  6. HeyBishop

    HeyBishop

    Joined:
    Jun 22, 2017
    Posts:
    238
    Thank you again. I'm a little closer now. Still struggling, but closer...

    In my TrackAsset, I figured out how to do a protected override. With it, I've been able to change the default duration:

    Code (CSharp):
    1. public class DialogTrack : TrackAsset
    2. {
    3.     ScriptPlayable<DialogMixer> scriptPlayable;
    4.     float clipDuration = 1f; // 1 is a temp value
    5.  
    6.     public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount)
    7.     {
    8.         scriptPlayable = ScriptPlayable<DialogMixer>.Create(graph, inputCount);      
    9.         return scriptPlayable;
    10.     }
    11.  
    12.     protected override void OnCreateClip(TimelineClip clip)
    13.     {
    14.         clip.duration = clipDuration;
    15.         base.OnCreateClip(clip);
    16.     }
    17. }
    The good news is, my clips are now defaulting to 1 second.
    The bad news is, I can't figure out how to reference a value on the playable to assign the clip.duration.
     
  7. HeyBishop

    HeyBishop

    Joined:
    Jun 22, 2017
    Posts:
    238
    Looks like we were typing at the same time...

    Yes, that's exactly what I'm trying to do.