Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Is Anyway to Change the Speed Multiplier of Timeline at runtime in unity c#

Discussion in 'Timeline' started by Rayfly0225, May 17, 2018.

  1. Rayfly0225

    Rayfly0225

    Joined:
    Jul 30, 2013
    Posts:
    4

    Is Anyway to Change the Speed Multiplier of Timeline at runtime in unity c#
    Could Someone can tell me the process?
     
  2. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    You can find the correct track using TimelineAsset.GetOutputTracks(), then find the correct clip using TrackAsset.GetClips(), then change the speed of the clip using TimelineClip.timeScale;

    Normally changes to the timeline itself does not change any instances of that timeline currently playing...but changing the speed of the clip will - Timeline uses a reference to the clip to convert to the local time of the clip.

    If you want to change the speed at which the entire timeline plays, after the timeline starts playing, you can modify the instance (playableGraph) directly. E.g. playableDirector.playableGraph.GetRootPlayable(0).SetSpeed(newSpeed);
     
  3. AnandNatarajan

    AnandNatarajan

    Joined:
    Jun 30, 2016
    Posts:
    2

    U R A Great.....!!!!!
     
    AmitChBB likes this.
  4. Riffar

    Riffar

    Joined:
    Jan 17, 2022
    Posts:
    2
    Wow, this just saved me hours of adjusting my clips in my 50+ tracks timeline ;-)
    Just to add the full code below, if anybody needs it (add this script to the timeline, drag timeline object into field pd and set new Speed in Inspector)

    using UnityEngine;
    using UnityEngine.Playables;
    public class TimelineSpeed : MonoBehaviour
    {
    public float newSpeed;
    public PlayableDirector pd;

    void Start()
    {
    pd = GetComponent<PlayableDirector>();
    pd.playableGraph.GetRootPlayable(0).SetSpeed(newSpeed);
    }
     
  5. Rockaso

    Rockaso

    Joined:
    Oct 31, 2016
    Posts:
    85
    Thanks for sharing, straight to the point!
     
  6. Whatever560

    Whatever560

    Joined:
    Jan 5, 2016
    Posts:
    463
    I implemented this as a fork of the Time dilation sample (available in the package) which now gives a IsGlobal boolean. And it seems to work pretty well, so now you can use timeline clip to directly control its speed (getting a kind of an inception vibe here ...)

    @julienb Would this be good to be added to the sample for it to be available to everyone ?


    Code (CSharp):
    1. namespace Timeline.Samples
    2. {
    3.     // Runtime representation of a time dilation clip.
    4.     // The Serializable attribute is required to be animated by timeline, and used as a template.
    5.     [Serializable]
    6.     public class TimeDilationBehaviour : PlayableBehaviour
    7.     {
    8.         [Tooltip("Time.timeScale replacement value.")]
    9.         public float timeScale = 1f;
    10.  
    11.         [Tooltip("Targets global game time or only current root timeline")]
    12.         public bool isGlobal = false;
    13.     }
    14. }
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Playables;
    3. using UnityEngine.Timeline;
    4.  
    5. namespace Timeline.Samples
    6. {
    7.     // A track mixer behaviour that modifies the timeScale. This affects how fast the game plays back
    8.     public class TimeDilationMixerBehaviour : PlayableBehaviour
    9.     {
    10.         private float m_DefaultTimeScale = 1;
    11.         private float m_DefaultPlayableSpeed;
    12.  
    13.         // Called every frame that the timeline is Evaluated.
    14.         public override void ProcessFrame(Playable playable, FrameData info, object playerData)
    15.         {
    16.             int inputCount = playable.GetInputCount();
    17.             float timeScale = 0f;
    18.             float playableSpeed = 0f;
    19.             float totalWeight = 0f;
    20.             float totalWeightSpeed = 0f;
    21.  
    22.             // blend clips together
    23.             for (int i = 0; i < inputCount; i++)
    24.             {
    25.                 float inputWeight = playable.GetInputWeight(i);
    26.  
    27.                 ScriptPlayable<TimeDilationBehaviour> playableInput = (ScriptPlayable<TimeDilationBehaviour>)playable.GetInput(i);
    28.                 TimeDilationBehaviour input = playableInput.GetBehaviour();
    29.  
    30.                 if (input.isGlobal)
    31.                 {
    32.                     timeScale += inputWeight * input.timeScale;
    33.                     totalWeight += inputWeight;
    34.                 }
    35.                 else
    36.                 {
    37.                     playableSpeed += inputWeight * input.timeScale;
    38.                     totalWeightSpeed += inputWeight;
    39.                 }
    40.  
    41.             }
    42.  
    43.             if (totalWeight > 0)
    44.             {
    45.                 // blend to/from the default timeline
    46.                 Time.timeScale = Mathf.Max(0.0001f, Mathf.Lerp(m_DefaultTimeScale, timeScale, Mathf.Clamp01(totalWeight)));
    47.             }
    48.  
    49.             if (totalWeightSpeed > 0)
    50.             {
    51.                 GetRootTimeline(playable).SetSpeed(Mathf.Max(0.0001f, Mathf.Lerp(m_DefaultPlayableSpeed, playableSpeed, Mathf.Clamp01(totalWeightSpeed))));
    52.             }
    53.        
    54.         }
    55.  
    56.         private static Playable GetRootTimeline(Playable playable)
    57.         {
    58.             return playable.GetGraph().GetRootPlayable(0);
    59.         }
    60.  
    61.         // Called when the playable graph is created, typically when the timeline is played.
    62.         public override void OnPlayableCreate(Playable playable)
    63.         {
    64.             m_DefaultTimeScale = Time.timeScale;
    65.             m_DefaultPlayableSpeed = (float)GetRootTimeline(playable).GetSpeed();
    66.         }
    67.  
    68.         // Called when the playable is destroyed, typically when the timeline stops.
    69.         public override void OnPlayableDestroy(Playable playable)
    70.         {
    71.             Time.timeScale = m_DefaultTimeScale;
    72.             playable.SetSpeed(m_DefaultPlayableSpeed);//Needed ?
    73.         }
    74.     }
    75. }
    76.  
     
    Last edited: Apr 18, 2023
  7. Whatever560

    Whatever560

    Joined:
    Jan 5, 2016
    Posts:
    463
    [Edit] : Fixed, our .gitignore had filtered out folder with "Samples' in the name.
    The timeline speed works good within the editor both at play and edit time. However it does not modify the speed the in build. Is there somehting I'm overlooking on how playables work ?
     
    Last edited: Apr 18, 2023