SetDuration of playable asset

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?

using UnityEngine;
using UnityEngine.Playables;

public class DialogClip : PlayableAsset
{
    [TextArea(2, 10)]
    public string captionText;
    public AudioClip audioClip;

    public override Playable CreatePlayable(PlayableGraph graph, GameObject owner)
    {
        var playable = ScriptPlayable<DialogBehaviour>.Create(graph);
       
        DialogBehaviour dialogBehaviour = playable.GetBehaviour();

        dialogBehaviour.captionText = captionText;
        dialogBehaviour.audioClip = audioClip;
        playable.SetDuration(audioClip.length);  ///////// this seems to do nothing

        return playable;
    }
}
using UnityEngine;
using UnityEngine.Playables;

public class DialogBehaviour : PlayableBehaviour
{
    public string captionText;
    public AudioClip audioClip;
}
using UnityEngine.Playables;

public class DialogMixer : PlayableBehaviour
{
    public override void ProcessFrame(Playable playable, FrameData info, object playerData)
    {
        ActorManager actor = playerData as ActorManager;

        string currentText = "";
        float currentAlpha = 0f;

        if (!actor) { return; }



        int inputCount = playable.GetInputCount();
        for (int i = 0; i < inputCount; i++)
        {
            float inputWeight = playable.GetInputWeight(i);

            if (inputWeight > 0f)
            {
                ScriptPlayable<DialogBehaviour> inputPlayable = (ScriptPlayable<DialogBehaviour>)playable.GetInput(i);

                DialogBehaviour dialog = inputPlayable.GetBehaviour();
                currentText = dialog.captionText;
                currentAlpha = inputWeight;
            }
        }

        actor.speechBubble.captionText.text = currentText;
        actor.speechBubble.canvasGroup.alpha = currentAlpha;
    }
}
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;

[TrackBindingType(typeof(ActorManager))]
[TrackClipType(typeof(DialogClip))]
public class DialogTrack : TrackAsset
{
    public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount)
    {
        ScriptPlayable<DialogMixer> scriptPlayable = ScriptPlayable<DialogMixer>.Create(graph, inputCount);       

        return scriptPlayable;
    }
}

You need to set the duration of the PlayableAsset, not the duration of the Playable.

Here would probably be the best place.

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?

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)

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.

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:

public class DialogTrack : TrackAsset
{
    ScriptPlayable<DialogMixer> scriptPlayable;
    float clipDuration = 1f; // 1 is a temp value

    public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount)
    {
        scriptPlayable = ScriptPlayable<DialogMixer>.Create(graph, inputCount);      
        return scriptPlayable;
    }

    protected override void OnCreateClip(TimelineClip clip)
    {
        clip.duration = clipDuration;
        base.OnCreateClip(clip);
    }
}

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.

Looks like we were typing at the same time…

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