Search Unity

How to reference the object bound to the track from the drawer?

Discussion in 'Timeline' started by Crazy-Minnow-Studio, Mar 20, 2018.

  1. Crazy-Minnow-Studio

    Crazy-Minnow-Studio

    Joined:
    Mar 22, 2014
    Posts:
    1,399
    Is it possible to reference the object the track is bound to from the 'drawer' script? I wish to control the duration of the PlayableAsset via the PropertyDrawer script. I already have working code that sets the duration; however, for a specific use-case, I need to reference a field in the object the track is bound to in order to properly calculate the duration. I've tried so many ways to trace my way back to the object without success. Is it even possible, and if so, what is the best way to do so?

    The PlayableAsset (clip) is aware of the PlayableBehavior (behavior) definition and the track is aware of the behaviors on it via the mixer, but the drawer is applied to the behavior definition and there doesn't appear to be a link back to the track's bound object reference except when overriding the ProcessFrame(Playable playable, FrameData info, object playerData) method, using the passed in playerData at runtime. I'm looking for the editor/design-time version of this.

    Any help, hugely appreciated!!! Thanks!
     
  2. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    That's a bit tricky but you can use the CreateTrackMixer() override to help here. While not it's intended purpose, it is being used in custom tracks to do things like rename clips because it's one spot where all the information is available.

    E.g.

    Code (CSharp):
    1.         public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount)
    2.         {
    3.             var director = go.GetComponent<PlayableDirector>();
    4.             if (director != null)
    5.             {
    6.                 var boundObject = director.GetGenericBinding(this);
    7.                 if (boundObject != null)
    8.                 {
    9.                     foreach (var clip in GetClips())
    10.                     {
    11.                         if (clip.asset != null)
    12.                         {
    13.                             // assign asset properties based on the boundObject here..                  
    14.                         }
    15.                     }              
    16.                 }
    17.             }
    18.            
    19.             return base.CreateTrackMixer(graph, go, inputCount);
    20.         }
    Note, that this gets called somewhat frequently in editor when the timeline structure changes.
     
    Fishing_Cactus likes this.
  3. Crazy-Minnow-Studio

    Crazy-Minnow-Studio

    Joined:
    Mar 22, 2014
    Posts:
    1,399
    Thanks @seant_unity !!! I think this is exactly what I needed. I added your code to my track script's CreateTrackMixer() override and ended up creating a new field in my behavior to hold the reference to the track's bound object. I needed this so I could continually update the field's duration and prevent it being resized manually. Now I can reference the bound object in the drawer script to make my computations from the bound object's fields and clip's behavior fields as I change them in the drawer. This is basically what I did (subset of above):

    Code (CSharp):
    1. if (clip.asset != null)
    2. {
    3.     // assign asset properties based on the boundObject here..
    4.     var customClip = clip.asset as CustomClipType;
    5.     customClip.template.refField = boundObject;
    6. }
    Is this a reasonable way to handle this?
     
  4. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    Reasonable enough! Hopefully we'll have some better apis for this problem soon! :)
     
    Crazy-Minnow-Studio likes this.