Search Unity

Set playable duration in code

Discussion in 'Timeline' started by Mars91, Jul 13, 2017.

  1. Mars91

    Mars91

    Joined:
    Mar 6, 2012
    Posts:
    398
    Hi,
    I'm working on a dialog/subtitle playable and everything is working like a charm, my only problem is that I can't figure out how to set the playable duration in the code.
    I have an AudioClip and I would like to set playable duration the same of AudioClip lenght.
     
  2. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,010
    This is a known issue, and something we want to address. You can override the duration property in your PlayableAsset representing your clip, and set it to the the audio clip length.

    As an example, here is how we do the duration for the audio clip track (the extra math keeps better frame alignment):

    Code (CSharp):
    1.         public override double duration
    2.         {
    3.             get
    4.             {
    5.                 if (m_Clip == null)
    6.                     return base.duration;
    7.  
    8.                 // use this instead of length to avoid rounding precision errors,
    9.                 return (double)m_Clip.samples / (double)m_Clip.frequency;
    10.             }
    11.         }

    The problem is typically you create the clip prior to assigning the audio clip, so you need to pick a default when nothing is assigned. Once the audio clip is assigned, if you right click on the clip and go to Editing -> Reset Editing it will change the length to the audio clip in that case.

    Some of the customization improvements on our backlog is to better support drag and drop for custom types. That would allow drag and drop of an audio clip to your custom track to assign the audio clip before determining a default length.
     
    Thomas-Bousquet likes this.
  3. Mars91

    Mars91

    Joined:
    Mar 6, 2012
    Posts:
    398
    Hi and thank you so much for your answer. In which one of the various scripts which compose the playable should I write that code?
     
  4. renaudbedard_SEM

    renaudbedard_SEM

    Joined:
    Sep 29, 2016
    Posts:
    4
    Is there any API to invoke this "Reset Editing" functionality by code? Would be great to auto-size clips that are generated by code.
     
  5. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,010
    Reset Editing doesn't have an API call, but if you create the clip via code, you should be able to something like

    Code (CSharp):
    1. var clip = track.CreateDefaultClip();
    2. clip.duration = (double) audioClip.sample / audioClip.frequency;
     
  6. renaudbedard_SEM

    renaudbedard_SEM

    Joined:
    Sep 29, 2016
    Posts:
    4
    That totally works, thanks! :)
     
  7. WikkidEdd1

    WikkidEdd1

    Joined:
    Nov 17, 2015
    Posts:
    10
    If you want the duration to update when you're changing the audio clip you can do it by creating a custom property drawer for your behaviour and implementing the following code.

    Taking @FootprintGames's example of dialog/subtitle track assuming you have a clip with a behaviour "template" similar to created by the playables wizard and an ExposedReference<AudioClip> variable on the clip.

    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEngine;
    3.  
    4. [CustomPropertyDrawer(typeof(SubtitleBehaviour))]
    5. public class SubtitleBehaviourDrawer : PropertyDrawer
    6. {
    7.     public override float GetPropertyHeight (SerializedProperty property, GUIContent label)
    8.     {
    9.         return EditorGUI.GetPropertyHeight(property, true);
    10.     }
    11.  
    12.     public override void OnGUI (Rect position, SerializedProperty property, GUIContent label)
    13.     {
    14.         // Draw the behaviours properties
    15.         EditorGUI.PropertyField(position, property, true);
    16.  
    17.         // Find the clip this behaviour is associated with a grab the audio clip
    18.         SubtitleClip clip = property.serializedObject.targetObject as SubtitleClip;
    19.         AudioClip audioClip = clip._Audio.Resolve(property.serializedObject.context as IExposedPropertyTable);
    20.         if(audioClip)
    21.         {
    22.             // Assume that the currently selected object is the internal class UnityEditor.Timeline.EditorClip
    23.             // this gives you access to the clip start, duration etc.
    24.             SerializedObject editorGUI = new SerializedObject(Selection.activeObject);
    25.  
    26.             // Grab the duration, set and apply modified properties
    27.             SerializedProperty duration = editorGUI.FindProperty("m_Clip.m_Duration");
    28.             duration.doubleValue = (double) audioClip.samples / audioClip.frequency;
    29.             editorGUI.ApplyModifiedProperties();
    30.         }
    31.     }
    32. }
    33.  
    You can then change the audio clip and see the clip duration update.
     
    KristianHJ likes this.
  8. KristianHJ

    KristianHJ

    Joined:
    May 28, 2010
    Posts:
    224
    Thanks, this helped me a bit closer to finding a solution my (unrelated) problem.
    I'm trying to select specific UnityEditor.Timeline.EditorClip's in a timeline from another script.
    Basically what I want to do is to set Selection.activeObject = *Some Editorclip*.

    My problem is that I cant figure out how to locate the references to editorclips, do you know where I can find the editorclips relative to a specific Timeline track?

    Any bright ideas?
     
  9. jwvanderbeck

    jwvanderbeck

    Joined:
    Dec 4, 2014
    Posts:
    604
    How would I go about getting the bound GO from the track so I could set the duration based on its data?
     
  10. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,010
    The GO passed to CreatePlayable or CreateTrackMixer is the game object that contains the playing playable director. From the playable director you can use GetGenericBinding, passing the track as the key, to get the binding for that track. You will need to cast it to your specific type.
     
  11. Crazy-Minnow-Studio

    Crazy-Minnow-Studio

    Joined:
    Mar 22, 2014
    Posts:
    897
    Note: FindProperty root is "m_Item" vice "m_Clip" in Unity 2017.2+.
     
    SeigoSato likes this.