Search Unity

DefaultPlayables: Is ExposedReference inspector broken or am misunderstanding how to set them?

Discussion in 'Timeline' started by bac9-flcl, Sep 4, 2018.

  1. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    829
    I watched the entire presentation about custom playables and DefaultPlayables package from James Bouckley and wanted to give the Default Playables asset a try. The whole system is pretty understandable and simple to use - or so I thought, until I tried to use Transform Tween Track and other examples from the Default Playables package which made use of ExposedReference fields within clips. Creating a Transform Tween Track and inserting a clip onto that track greeted me with this inspector:



    That inspector shows me the state of a TransformTweenClip class instance, which is organized like this internally - pretty much like the sample tween class covered in the talk:

    Code (csharp):
    1.  
    2. public class TransformTweenClip : PlayableAsset, ITimelineClipAsset
    3. {
    4.     public TransformTweenBehaviour template = new TransformTweenBehaviour ();
    5.     public ExposedReference<Transform> startLocation;
    6.     public ExposedReference<Transform> endLocation;
    7.     ...
    The inspector is actually drawn from two places. Three fields on top (position, rotation, type) belong to the template container, and are are drawn by TransformTweenDrawer class - an ordinary property drawer class almost exactly replicating one covered in the talk by James.

    Below, ExposedReference<Transform> fields are drawn using... no idea what (probably some internal class from UnityEditor which I wasn't able to trace). And this is where I became completely stumped - these fields look wrong and don't actually give me any way to fill the clip with proper scene references. Let's take a closer look at the first ExposedReference field in this class.



    Unfortunately, the talk never featured a single screenshot of an inspector of a clip class with an ExposedReference field in it - nor did any third-party tutorials on YouTube, so I'm just guessing that the inspector renders the field wrong.

    But based on my understanding of idea behind ExposedReference struct and on verbal descriptions from the presentation by James, the field should look like an ordinary reference field - a plain box you can drag scene objects into, and it should use the dragged objects to fill the PropertyName exposedName field - for later retrieval of a given object from PlayableGraph through Resolve calls. Instead, what we're seeing here seems like a "naked", default-like inspector for ExposedReference, with the PropertyName and default reference shown directly and no decoration hiding them away. It's impossible to actually make a clip reference anything in the scene with this inspector - you can validate it yourself by adding logging after Resolve calls into the TransformTweenClip class, like this:

    Code (csharp):
    1.  
    2. [Serializable]
    3. public class TransformTweenClip : PlayableAsset, ITimelineClipAsset
    4. {
    5.     public TransformTweenBehaviour template = new TransformTweenBehaviour ();
    6.     public ExposedReference<Transform> startLocation;
    7.     public ExposedReference<Transform> endLocation;
    8.  
    9.     public ClipCaps clipCaps
    10.     {
    11.         get { return ClipCaps.Blending; }
    12.     }
    13.  
    14.     public override Playable CreatePlayable (PlayableGraph graph, GameObject owner)
    15.     {
    16.         var playable = ScriptPlayable<TransformTweenBehaviour>.Create (graph, template);
    17.         TransformTweenBehaviour clone = playable.GetBehaviour ();
    18.         clone.startLocation = startLocation.Resolve (graph.GetResolver ());
    19.         clone.endLocation = endLocation.Resolve (graph.GetResolver ());
    20.  
    21.         Debug.Log
    22.         (
    23.             "Start location ExposedReference was resolved " + (clone.startLocation == null ? "to null" : "successfully") +
    24.             " | End location ExposedReference was resolved " + (clone.endLocation == null ? "to null" : "successfully")
    25.         );
    26.  
    27.         return playable;
    28.     }
    29. }
    Initially, I was wondering whether I misunderstood something and whether default value field was the right place to drag my scene objects into. But logging the resolution results and rechecking the talk confirmed to me that default value field has no effect on resolution (the logs told me the result is always null even if default value is filled) and shouldn't even be shown in the inspector.

    So, to summarize, here is my current understanding of the situation:

    • ExposedReference fields are never included into custom property drawers for custom clips
    • Instead of making you decorate them directly from a custom clip inspector, Unity has some sort of internal Editor class responsible for drawing a default inspector for these fields
    • At some point in the recent past (around 2018.1 at the very latest, which is when I first tried the asset), that internal inspector-generating class was removed or became broken
    • As a result, ExposedReference fields are currently not decorated with a proper GUI disguising them as ordinary reference fields and properly filling those fields with data (exposedName).
    • Consequently, it's currently impossible to reference anything in clips using ExposedReference fields, like TransformTweenClip from DefaultPlayables asset

    Please correct me if I'm wrong somewhere. Maybe it's really a bug that just wasn't noticed for a while, since none of default Timeline tracks shipping with Unity Editor use ExposedReference fields in the clips, so you can only encounter the issue while checking the Default Playables asset or writing a custom track similar to transform tween example from the talk.
     
    Last edited: Sep 4, 2018
  2. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    That's odd. Timeline does use ExposedReferences on Control Track clips, and I haven't seen them behave that way. I've even downloaded James example and it worked as expected (in 2018.2).

    You are right about a 'naked' inspector, it looks as if the drawer for ExposedReferences isn't being loaded correctly. You can try a control track, and see if the Source Game Object field is working correctly. My only other suggestion off the top of my head is to file a bug. Having the repro case always makes it easier to get to the bottom of it!.
     
  3. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    829
    Glad to hear that's not how inspectors are supposed to look. You're right, I forgot about Control Tracks - dragging GameObjects into Control Tracks seems to create clips with a reasonable looking inspector.



    I'm not sure how ExposedReference field inside of that clip is filled/used (and truth to be said, Control Tracks are the one and only Timeline track type that I don't yet understand at all how to use), but I suppose a different looking inspector is proof enough that this is an issue localized to Default Playables and custom playables creating following the model from it.

    What can I look into next? For instance, what is the name of the drawer class that's supposed to decorate ExposedReference fields, so that I can check my project for possible conflicts and check managed source on GitHub for more ideas?
     
  4. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    829
    Figured it out thanks to the help from Tor Vestergaard from Sirenix - it looks like the issue was caused by the popular Odin Inspector asset taking over the drawers in this inspector. In case anyone stumbles into this thread while searching for a solution to the same issue, the fix is to create an ExposedReferenceDrawer class in any Editor folder, with the following content (which would stop Odin Inspector from taking over ExposedReference fields):

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using Sirenix.OdinInspector.Editor.Drawers;
    4.  
    5. public sealed class ExposedReferenceDrawer<TValue> : DrawWithUnityBaseDrawer<ExposedReference<TValue>>
    6.     where TValue : UnityEngine.Object
    7. {
    8. }
    No bugs on the Unity side here, sorry for the false alarm! :)
     
  5. lingumigeorge

    lingumigeorge

    Joined:
    Nov 21, 2016
    Posts:
    7
    Thanks for this!

    I also went into Odin Preferences and disabled Odin for all Clip types (which seems to work - just make sure to press save to preserve the changes/show it up in version control).
     
  6. artemio_morales

    artemio_morales

    Joined:
    Nov 29, 2015
    Posts:
    19
    My ExposedReferences were getting unset whenever the scene was unloaded and this was killing me, thanks so much for this! (OdinInspector was the culprit for me as well)