Search Unity

How do you lock the timeline panel programmatically?

Discussion in 'Timeline' started by tom_mardis, May 8, 2020.

  1. tom_mardis

    tom_mardis

    Joined:
    Mar 11, 2020
    Posts:
    10
    I was able to find how to lock the inspector panel:
    ActiveEditorTracker.sharedTracker.isLocked = (true or false)

    and I was able to get the EditorWindow object for the timeline but that class does not contain any methods to set the lock state of the panel.

    Is there an equivalent of ActiveEditorTracker.sharedTracker.isLocked for the timeline window/panel?
     
  2. gekidoslayer

    gekidoslayer

    Unity Technologies

    Joined:
    Sep 27, 2016
    Posts:
    134
    It's not public, you have to use reflection to access unfortunately.
     
  3. tom_mardis

    tom_mardis

    Joined:
    Mar 11, 2020
    Posts:
    10
    Thanks for responding! So I used this code to get the window:

    public EditorWindow GetEditorWindow(string name) {
    EditorWindow[] windows = Resources.FindObjectsOfTypeAll<EditorWindow>();
    if (windows != null && windows.Length > 0)
    {
    foreach (var window in windows)
    if (window.GetType().Name.Contains(name))
    return window;
    }
    return null;
    }

    EditorWindow timelineWindow = GetEditorWindow("Timeline");

    Is that sufficient to access the lock value? I didn't see a value in EditorWindow to change the lock value.

    If not would you mind showing an example?

    This would be really valuable for me because I"m creating an artist interface for creating 3D animations and locking the timeline keeps them out of trouble, and it also makes it possible to move objects in the scene without losing track of the current frame that the scrubber is on. (If the timeline window loses focus on a game object, it's timeline resets to zero.
     
  4. gekidoslayer

    gekidoslayer

    Unity Technologies

    Joined:
    Sep 27, 2016
    Posts:
    134
    The code that I have to do this isn't broken into a single method to make it easy to copy-pasta, but this is how my custom timeline tools toggle the lock status:

    Toggle the Lock status
    Code (CSharp):
    1. public static void ToggleLock()
    2.         {
    3.             var window = GetWindow();
    4.             PropertyInfo propertyInfo = window.GetType().GetProperty("locked");
    5.             bool value = (bool)propertyInfo.GetValue(window, null);
    6.             propertyInfo.SetValue(window, !value, null);
    7.             window.Repaint();
    8.         }
    Set the lock status:

    Code (CSharp):
    1. public static void SetLockStatus(bool newState)
    2.         {
    3.             var window = GetWindow();
    4.             PropertyInfo propertyInfo = window.GetType().GetProperty("locked");
    5.             propertyInfo.SetValue(window, newState, null);
    6.             window.Repaint();
    7.         }
    etc...you should get the idea
     
    tom_mardis likes this.
  5. gekidoslayer

    gekidoslayer

    Unity Technologies

    Joined:
    Sep 27, 2016
    Posts:
    134
    To get a handle to the timeline window you can do this:

    Code (CSharp):
    1. public static readonly Type timelineWindow =
    2.             Type.GetType("UnityEditor.Timeline.TimelineWindow, Unity.Timeline.Editor");
    3.  
    4. public static EditorWindow GetWindow()
    5.         {
    6.             // make sure the window is open
    7.             EditorApplication.ExecuteMenuItem("Window/Sequencing/Timeline");
    8.  
    9.             var timelineWindowType = TimelineBase.timelineWindow;
    10.  
    11.             // Assuming there always only one timeline window
    12.             var timeline_window = Resources.FindObjectsOfTypeAll(timelineWindowType)[0] as EditorWindow;
    13.             return timeline_window;
    14.         }
     
    tom_mardis likes this.
  6. tom_mardis

    tom_mardis

    Joined:
    Mar 11, 2020
    Posts:
    10
    That worked! Wow, that made a big difference in the usability of my workflow. Thank you so much I really appreciate you responding so quickly and taking the time to give excellent code examples!
     
  7. gekidoslayer

    gekidoslayer

    Unity Technologies

    Joined:
    Sep 27, 2016
    Posts:
    134
    Cool, glad to hear. This was a part of the Timeline tools /w extensions created for the Baymax / Sherman projects, still negotiating to see if I can get them officially adopted ;)
     
    Last edited: May 9, 2020
    tom_mardis likes this.
  8. troynall

    troynall

    Joined:
    May 19, 2018
    Posts:
    10
    using UnityEditor;
    using UnityEngine;

    public class CustomInspectorTools : EditorWindow
    {
    [MenuItem("Window/Custom Inspector Tools")]
    public static void ShowWindow()
    {
    GetWindow<CustomInspectorTools>("Custom Inspector Tools");
    }

    private void OnGUI()
    {
    if (GUILayout.Button("Toggle Inspector Lock"))
    {
    ToggleInspectorLock();
    }
    }

    private void ToggleInspectorLock()
    {
    ActiveEditorTracker.sharedTracker.isLocked = !ActiveEditorTracker.sharedTracker.isLocked;
    ActiveEditorTracker.sharedTracker.ForceRebuild();
    }
    }
     
  9. akent99

    akent99

    Joined:
    Jan 14, 2018
    Posts:
    588
    That code locks the inspector window, not the Timeline Editor, right? Here is some code I use (on modern implementations of TimelineWindow etc - more APIs are now public). It locks the Timeline window by default on startup, so you don't have to remember to click the lock button each time you start the editor. You have to have a timeline selected to be able to lock the window, so it looks for a random Timeline in the scene hierarchy, then climbs up the parent hierarchy in case its using the Sequences package (which is what I do). Then once a Timeline is selected, it locks the timeline editor window. This all happens once when the editor starts up.

    Code (csharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEditor;
    5. using System;
    6. using System.Reflection;
    7. using UnityEditor.Timeline;
    8. using UnityEngine.Playables;
    9. [InitializeOnLoad]
    10. public class TimelineWindowLockOnLoad
    11. {
    12.     static TimelineWindowLockOnLoad()
    13.     {
    14.         // Register a callback for when after the editor window is initialized.
    15.         EditorApplication.update += Update;
    16.     }
    17.  
    18.     static void Update()
    19.     {
    20.         // Remove the callback (once is all we are going to do)
    21.         EditorApplication.update -= Update;
    22.  
    23.         // Find the timeline window. (Could call GetOrCreateWindow().
    24.         var timelineEditorWindow = TimelineEditor.GetWindow();
    25.         if (timelineEditorWindow != null)
    26.         {
    27.             // Find a Timeline component, then in case we are using Sequences, climb up to the root master sequence.
    28.             var timeline = UnityEngine.Object.FindObjectOfType<PlayableDirector>();
    29.             while (timeline.transform.parent != null && timeline.transform.parent.GetComponent<PlayableDirector>() != null)
    30.             {
    31.                 timeline = timeline.transform.parent.GetComponent<PlayableDirector>();
    32.             }
    33.             if (timeline != null)
    34.             {
    35.                 // We have to select a timeline first, then we can set locked to true.
    36.                 timelineEditorWindow.SetTimeline(timeline);
    37.                 timelineEditorWindow.locked = true;
    38.             }
    39.         }
    40.     }
    41. }
     
    EmissiveUnity8 likes this.