Hello, I’m trying to figure out how to resolve an ExposedReference from within a Marker.
I’ve seen in several places how to do it for a PlayableAsset (a clip?):
public ExposedReference<Transform> exposedTransform;
public override Playable CreatePlayable(PlayableGraph graph, GameObject owner)
{
var playable = ScriptPlayable<AddBloodBehaviour>.Create(graph);
actualTransform = exposedTransform.Resolve(graph.GetResolver());
return playable;
}
How could I resolve this exposedTransform if I was using a Marker? I don’t know how to access the ‘graph’ from the Marker itself. I see that it has “parent” which is the TrackAsset, and the “timelineAsset” from there, but I’m not sure if there is a way to get to the “graph” from there so I can use graph.GetResolver().
And just to clarify, I know how to set up the INotificationReceiver and resolve the ExposedReference on that. I just don’t know how to do it on the Marker itself.
My end goal is to be able to add an ExposedReference to a Marker, and then also display the inspector for MySpecialComponent so that I can modify it while I have the Marker selected. Is this possible?
To resolve an exposed reference from an Editor (inspector) class, you can cast the Selection’s active context as a PlayableDirector. When a Timeline clip/marker is selected, Timeline automatically puts the PlayableDirector as a context object. This will let you resolve the exposed reference in your Marker object.
public class TestMarker : Marker
{
public ExposedReference<Light> light;
}
[CustomEditor(typeof(TestMarker))]
public class TestMarkerInspector : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
//when a Timeline clip/marker is selected, the director is added as a context object
var directorContext = Selection.activeContext as PlayableDirector;
var inspectedMarker = target as TestMarker;
if (directorContext != null && inspectedMarker != null)
{
PropertyName referenceExposedName = inspectedMarker.light.exposedName;
Light lightReference = directorContext.GetReferenceValue(referenceExposedName, out bool isValid) as Light;
if (isValid && lightReference != null)
{
Editor inspector = CreateEditor(lightReference);
inspector.OnInspectorGUI();
}
}
}
}
Now I can display the Light’s inspector embedded in the custom Marker inspector:
@julienb Thank you, this worked perfectly. This was the last thing I needed to figure out for my Timeline implementation (knock on wood), so I seriously appreciate the explanation and the example!
@julienb I tried your suggestion in 2021.1 and 2021.2 but my Selection.activeContexis always null. I’m currently trying this for a custom inspector for a timeline clip (not a marker as in your example) but you mentioned that it would work for clips (ITimelineClipAsset) as well, right?
Is this documented somewhere or do you know a different way to resolve exposed references? My current workaround is to set properties during CreatePlayable where I have access to the graph but this happens after ClipEditor::OnClipChanged and it’s not very stable.
I’m trying to set the duration of a clip based on an exposed reference.