Search Unity

  1. New Unity Live Help updates. Check them out here!

    Dismiss Notice

Timeline editor customization

Discussion in 'Timeline' started by Sangemdoko, Jan 10, 2020.

  1. Sangemdoko

    Sangemdoko

    Joined:
    Dec 15, 2013
    Posts:
    70
    Hi, I would like to customize the markers and clip styles in the timeline editor for an asset I am making.

    For now I know that I can create new markers with custom styles using the Attribute:
    [CustomStyle("Mystyle")]
    And that allows me to set the Width, Height and background-color properties. Other properties like color, background-color or -unity-background-image-color-tint do not do anything.

    I would like something more flexible where I could dynamically change the marker image/style depending on its state (which could be set in the inspector). For example, the Signal Emitter marker has a special icon when no signals are attached.

    In my setup, I have to create a new Marker class for each state just so that I can have different icons for each. It would be a lot nicer If I could have a single custom marker that changes visual and functionality depending on its state.

    Any advice is welcome.
     
  2. julienb

    julienb

    Unity Technologies

    Joined:
    Sep 9, 2016
    Posts:
    146
    You can draw an overlay on top of a marker by using a MarkerEditor:
    Code (CSharp):
    1. public class MyMarker : Marker { }
    2.  
    3. //Make sure to put this class in its own file in an Editor directory, so that it is not included in a build
    4. [CustomTimelineEditor(typeof(MyMarker))]
    5. public class MyMarkerEditor : MarkerEditor
    6. {
    7.     public override void DrawOverlay(IMarker marker, MarkerUIStates uiState, MarkerOverlayRegion region)
    8.     {
    9.         EditorGUI.DrawRect(region.markerRegion, Color.cyan);
    10.     }
    11. }
    Without MyMarkerEditor: upload_2020-1-10_11-5-21.png With MyMarkerEditor: upload_2020-1-10_11-3-53.png

    You can also do the same with clips.
     
  3. Sangemdoko

    Sangemdoko

    Joined:
    Dec 15, 2013
    Posts:
    70
    Thank you, That'll help a lot!

    Are there any plans to convert the Timeline editor to UIElements anytime soon? Just curious
     
  4. julienb

    julienb

    Unity Technologies

    Joined:
    Sep 9, 2016
    Posts:
    146
    No, there aren't any plans right now to convert the Timeline window to UIElements.
     
  5. Sangemdoko

    Sangemdoko

    Joined:
    Dec 15, 2013
    Posts:
    70
    Thanks.

    So I made the change to have a single Marker type with different states.
    But now I have a new problem. When I copy paste some markers they set to the default state instead of keeping the state of the copied marker. By state I mean I have a property field on my marker which I can change in the inspector.

    In my workflow there is a ton of copy-pasting because I use a lot of markers, having to set each marker manually after they are copied would be a deal-breaker.

    Any advice, maybe there's an editor function that I can override for copy-pasting? ... I'll be very sad if I have to change everything back since it took me an entire day to make that change.
     
  6. Sangemdoko

    Sangemdoko

    Joined:
    Dec 15, 2013
    Posts:
    70
    Ok so I should have read the documentation better, there's a function to override copy:

    Code (CSharp):
    1.  public override void OnCreate(IMarker marker, IMarker clonedFrom)
    2.         {
    3.             base.OnCreate(marker, clonedFrom);
    4.         }
    But in the end I won't use the state stuff, I was overcomplicated things for nothing...
    Thank you for the help though, I'll still use the MarkerEditor code for better customization
     
  7. Sangemdoko

    Sangemdoko

    Joined:
    Dec 15, 2013
    Posts:
    70
    Ok I have a new question.

    When you have two or more markers in the same space, the default marker adds a little "+" icon on top of the marker.

    My overlay hides that little "+" icon. The thing is that I do not know how to get the information that two markers are overlapping so that I can add my own little "+".

    Any tricks you can give me is very appreciated!
     
  8. julienb

    julienb

    Unity Technologies

    Joined:
    Sep 9, 2016
    Posts:
    146
    Unfortunately, the overlay is drawn on top of the markers, which includes the little + icon. The best you can do is to check the other markers on the track, and display a + icon if two markers are ''close'' (their time is approximately equal). This is what we do internally.
     
  9. Sangemdoko

    Sangemdoko

    Joined:
    Dec 15, 2013
    Posts:
    70
    Thanks! I didn't think of that.
    I'll do the same then
     
  10. Sangemdoko

    Sangemdoko

    Joined:
    Dec 15, 2013
    Posts:
    70
    For some reason the + icon just started appearing without me writing the code for it. I wonder if the script execution order changed. For now it works so great!
    Since I tested the marker editor and got the results I wanted I'm now trying it the clip editor. But I feel like what I'd like to do is simply not possible. I'd like to draw an icon at the start and end position of the clip. The thing is that the icons get cut in half. It seems like I cannot draw outside the clip region...which to be fair makes sense.
    Is there a way to draw outside that region?
    If not, it's not a deal breaker I feel like I can still get the point across. If need be I could always shift the icons inside... but I'd prefer the center to be exactly on start and end.
    Here is how my custom stuff looks like so far, I'll just need to swap out the icons and I'm good to go.
    upload_2020-1-17_17-37-51.png
     
  11. HopeErin

    HopeErin

    Joined:
    Sep 12, 2019
    Posts:
    6
    Hey! I'm trying to do something simpler but similar (just add a red visual highlight to certain clips), could you share how you got this working on the clip?
     
  12. Sangemdoko

    Sangemdoko

    Joined:
    Dec 15, 2013
    Posts:
    70
    Sure, you need to create a new PlayableAsset class and create an editor for it. You can look at the documentation for more detail.
    https://docs.unity3d.com/Packages/com.unity.timeline@1.2/api/UnityEditor.Timeline.ClipEditor.html
    In case in can help you, here is my editor code for the editor clip above:


    Code (CSharp):
    1. [CustomTimelineEditor(typeof(BeatClipAsset))]
    2.     public class BeatAssetClipEditor : ClipEditor
    3.     {
    4.         public override void OnCreate(TimelineClip clip, TrackAsset track, TimelineClip clonedFrom)
    5.         {
    6.             base.OnCreate(clip, track, clonedFrom);
    7.  
    8.             var otherAsset = clonedFrom?.asset;
    9.  
    10.             (clip.asset as BeatClipAsset).Copy(otherAsset);
    11.         }
    12.  
    13.         public override void OnClipChanged(TimelineClip clip)
    14.         {
    15.             base.OnClipChanged(clip);
    16.         }
    17.  
    18.         public override void DrawBackground(TimelineClip clip, ClipBackgroundRegion region)
    19.         {
    20.             base.DrawBackground(clip, region);
    21.            
    22.             var beatAsset = clip.asset as BeatClipAsset;
    23.             var iconSize = new Vector2(18,18);
    24.            
    25.             var startRegion = new Rect(
    26.                 region.position.position.x-iconSize.x/2,
    27.                 region.position.position.y,
    28.                 iconSize.x,
    29.                 iconSize.y);
    30.             var endRegion = new Rect(
    31.                 region.position.position.x+region.position.width-iconSize.x/2,
    32.                 region.position.position.y,
    33.                 iconSize.x,
    34.                 iconSize.y);
    35.             var backgroundRegion = new Rect(
    36.                 region.position.position.x,
    37.                 region.position.position.y+iconSize.y/4,
    38.                 region.position.width,
    39.                 iconSize.y/2);
    40.  
    41.             var startTexture = (Texture)AssetDatabase.LoadAssetAtPath (beatAsset.EditorStartIconPath, typeof(Texture));
    42.             if (startTexture == null) {
    43.                 startTexture = (Texture) AssetDatabase.LoadAssetAtPath(BeatUtility.s_OnBeatIconPath, typeof(Texture));
    44.             }
    45.            
    46.             var endTexture = (Texture)AssetDatabase.LoadAssetAtPath (beatAsset.EditorEndIconPath, typeof(Texture));
    47.             if (endTexture == null) {
    48.                 endTexture = (Texture) AssetDatabase.LoadAssetAtPath(BeatUtility.s_OnBeatIconPath, typeof(Texture));
    49.             }
    50.  
    51.             var color = beatAsset.EditorColorPath;
    52.  
    53.             EditorGUI.DrawRect(backgroundRegion, color);
    54.            
    55.             Color previousGuiColor = GUI.color;
    56.             GUI.color = Color.clear;
    57.  
    58.             EditorGUI.DrawTextureTransparent(startRegion, startTexture);
    59.             EditorGUI.DrawTextureTransparent(endRegion, endTexture);
    60.            
    61.             GUI.color = previousGuiColor;
    62.            
    63.         }
    64.     }
    Best of luck
     
    HopeErin likes this.
unityunity