Custom inspector editor for timeline clips?

Any chance we’re going to be able to write custom editors for our clips in the tracks? It would really come in handy … if we’re already able to, please let me know how :).

Yeah, we can already do it.

using UnityEngine.Playables;

[CustomPropertyDrawer(typeof(EnemyControlBehaviour))]
public class EnemyControlDrawer : PropertyDrawer
{
    public override float GetPropertyHeight (SerializedProperty property, GUIContent label)
    {
        int fieldCount = 1;
        return fieldCount * EditorGUIUtility.singleLineHeight;
    }

    public override void OnGUI (Rect position, SerializedProperty property, GUIContent label)
    {
        SerializedProperty prefab = property.FindPropertyRelative("prefab");
        SerializedProperty color = property.FindPropertyRelative("color");

        Rect singleFieldRect = new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight);
        EditorGUILayout.PropertyField(prefab);
        EditorGUILayout.PropertyField(color);
    }
}

This is one of mine. It’s messy because I rushed it without actually reading what it was doing at first, but it works. The way he does in the video looks better, I think.

3 Likes

Woah had no idea this was implemented. Thank you sooo much.

How to do this for a track? I’ve got it only the clips… works well; but I’d love to be able to do this on a track

For a track you can simply use an Editor as described here.

1 Like

I know it’s an old post, but it’s something I am struggling with at the moment.
In general I understand the idea.
But I would like to combine two worlds.

Ability to record animations (example 4 from Unity Blog)
And custom editor.
If I follow the property drawer idea, yes I can override the inspector, but I can no longer record animations on that clip/behaviour inspector.
The red(record) button is visible and I can click it but no key frames can be recorded.

Before, with the automatic editor and the fact it generated “template” fields out of the box, I could record animations on clip inspector.
For now I need to choose, ability to record animation from clip inspector with automatic template fields generations or custom clip editor.

Is it me or maybe there is something missing in the video example?

[Update]
In general I only need to add some graphical element base on values so I can display default inspector and some added bits. Don’t need to change any values in my custom editor bit.

After some more digging I realized that extending behaviour editor wasn’t the issue.
Looks like I can’t really record animations on none float variables.
Maybe it has somethign to do with mixer and the fact there are calculations on float for input weight etc.
Sorry, my issue is not related to the custom behaviour editor.

I’m unable to write PropertyDrawer for my TimelineBehaviour with script AndrewKaninchen provided. I also tried to bind PropertyDrawer to MyCustomClip. I found no other info about it.

I’m also very interested in how AudioTrack drawing custom grapics (audio track presentation) over clips in Timeline window. I’m just curious, I bet I’ll come up with some interesting ideas with custom graphics and ui elements over clips :slight_smile:
At least I hope when timeline will be available as package we’ll be able to dig it through and see how it’s acheived

Oh dang it was really stupid tiny mistake I made. I figured out how to write PropertyDriwer

Timeline is (sort-of) a package in 2019.1. The package ships with Unity instead of using Package Manager (that might change in the future). But it means you can drag a local copy into your package folder and have a locally modified version.

Also - 2019.2 has added ClipEditors, TrackEditors and MarkerEditors to help customize. The waveforms are done using a ClipEditor, so it’s definitely possible. In fact, if you are deriving from AudioPlayableAsset, then you will get the waveform drawing by default.

1 Like

What a great future is coming :smile: I’m hacking into Timeline extensively in my current project. With tracks generation and manipulation through custom node editor. It’s cool to hear there is more to come. I love how we may extend some tools in unity in a ways it not intended to be used :slight_smile:

Hey Sean, would have some sample code on how to extend the markers? I’ve written a custom inspector for my new marker (derived from the standard “Editor” inspector class) in order to add some QoL improvements on top of the default inspector behavior. I’ve overriden OnInspectorGUI() and called DrawDefaultInspector() from it but I’m not getting the same behavior as the Unity default. For instance, I can no longer edit the marker name in the inspector header (I have a workaround but it’s not ideal):
4929422--478004--upload_2019-9-4_14-51-11.png

And this how it looks using the default marker inspector:
4929422--478007--upload_2019-9-4_14-52-6.png

I figured I should probably derive my custom inspector from something like a more specialized “MarkerEditor” base class but this one doesn’t seem to derive from the base Editor inspector class.

Any pointers please?

@spk that is a very fair question, and unfortunately the answer isn’t trivial :frowning:

Timeline does have the base class you are looking for, it’s call MarkerInspector. However, it is not a public class. Because timeline is a package, the source code is available to look at, and even change if you make the package local (not recommended unless you never plan on upgrading).

The marker inspector is using protected internal methods (OnHeaderTitleGUI) from UnityEditor.Editor to achieve the title bar editing.

You can override OnHeaderGUI in your custom inspector, but you need to re-implement the entire header, not just the title.

One approach that might work for you is to not use your own Editor (i.e. inspector) class, but use PropertyDrawers on individual members of your marker class. That should use the built-in marker inspector, and give you the title edit feature, and let you customize the OnGUI for individual fields of your marker class.

I hope that helps.

The MarkerEditor class that is public is to aid in the drawing of markers on the timeline, and not in the inspector. I’ve attached a sample that uses that for markers that act as snap points. Not completely relevant to your question, but if you are trying to customize markers it’s a useful example. Note that markers also support .uss files that let you customize the styling of the marker, which is a great way to get custom looks for the different markers.

4930229–478094–SnapPoint.cs (502 Bytes)
4930229–478097–SnapPointEditor.cs (4.17 KB)

Thanks for the detailed answer, sean! I can easily work around the title bar renaming feature by simply adding a custom text field to my inspector to update name property of the marker, but yeah it’s not ideal. I’ll give the property drawer approach a go, but in my case I would like to control the visibility of several fields depending on the value of an enum property so I’m not sure this approach would work here.

@seant_unity while I’ve got you on the line… is there an equivalent of Marker.parent (TrackAsset) for timeline clips in the editor? I’m trying to do a custom inspector for a new timeline clip that has a property that should list markers on the timeline the clip is on. Unfortunately the PlayableAsset class from which my custom clip derives from does not know about the timeline track it’s on, so I cannot enumerate the markers it contains.

Is there a more specialized base-class to derive from for timeline clips? As in, the equivalent of the Marker class but for clips?

For the property drawer approach, you can put the enum and associated fields in a struct which has it’s own property drawer.

For clips, not really. By design, markers are a bit different than clips. Clips are classes (not UnityEngine.Object derived) and are serialized with the track, and have a reference to a playable asset. Markers are themselves ScriptableObjects that live as sub assets of the timeline, and implement the IMarker interface.

There are posts about how to assign the clip to the playable asset (e.g. custom clip class) using TrackAsset.CreateTrackMixer, but you can also use the clip editor to do it. Something like

public override ClipDrawOptions GetClipOptions(TimelineClip clip)
{
var asset = (MyCustomClip) clip.asset;
asset.parentClip = clip; // assumes parentClip is a property of MyCustomClip, and not a serialized field.
return base.GetClipOptions(clip);
}

Alternately in your custom editor you can search TimelineEditor.inspectedAsset for the clip that has your particular asset. Not the most efficient way, but if done in OnEnable, it is probably fine.

If you store a reference to the clip, because careful not to serialize it. Because TimelineClip is a plain old serializable class, when the timeline is reloaded off disk, that will create a copy and no longer refer to the original. This can cause a lot of bugs and confusion.

1 Like