Search Unity

Getting objectData before ProcessFrame is called

Discussion in 'Timeline' started by Rodolinc, Jan 24, 2019.

  1. Rodolinc

    Rodolinc

    Joined:
    Sep 23, 2013
    Posts:
    63
    Hi, I'm making a custom playable where I need the reference to the referenced asset in the CustomTrackAsset. I don't know if it's possible because the ProcessFrame in the PlayableBehavior script gets called last, and I need that reference for the OnBehaviourPlay method which gets called before ProcessFrame.

    Notice in the behaviour script OnBehaviourPlay, there is where I need the "GameObject" reference.

    Clip:
    Code (CSharp):
    1. public class CustomPlayableAsset : PlayableAsset
    2. {    
    3.     public bool toLoad;
    4.  
    5.     public override Playable CreatePlayable(PlayableGraph graph, GameObject owner)
    6.     {
    7.         var playable = ScriptPlayable<CustomPlayableBehavior>.Create(graph);
    8.  
    9.         var scenePlayableBehavior = playable.GetBehaviour();
    10.         scenePlayableBehavior.toLoad = toLoad;
    11.         return playable;
    12.     }
    13. }
    Behavior:
    Code (CSharp):
    1. [System.Serializable]
    2. public class CustomPlayableBehavior : PlayableBehaviour
    3. {
    4.     [Tooltip("true = load, false = unload")]
    5.     public bool toLoad;
    6.     GameObject gameObject;
    7.  
    8.     //like the Update
    9.     public override void ProcessFrame(Playable playable, FrameData info, object playerData)
    10.     {
    11.         gameObject =  playerData as GameObject;
    12.     }
    13.    
    14.     public override void OnBehaviourPlay(Playable playable, FrameData info)
    15.     {
    16.         base.OnBehaviourPlay(playable, info);
    17.         if (gameObject != null)
    18.         {
    19.             //THIS DOESNT EXECUTE BECAUSE ITS NULL
    20.         }
    21.     }
    22. }
    Track:
    Code (CSharp):
    1. [TrackColor(0, 0, 0)]
    2. [TrackClipType(typeof(CustomPlayableAsset))]
    3. [TrackBindingType(typeof(GameObject))]
    4. public class CustomPlayableTrack : TrackAsset
    5. {
    6.     public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount)
    7.     {
    8.         return ScriptPlayable<CustomPlayableBehavior>.Create(graph, inputCount);
    9.     }
    10.     public override void GatherProperties(PlayableDirector director, IPropertyCollector driver)
    11.     {
    12.         base.GatherProperties(director, driver);
    13. #if UNITY_EDITOR
    14.         var comp = director.GetGenericBinding(this);
    15.         if (comp == null)
    16.             return;
    17.         var so = new UnityEditor.SerializedObject(comp);
    18.         var iter = so.GetIterator();
    19.         while (iter.NextVisible(true))
    20.         {
    21.             if (iter.hasVisibleChildren)
    22.                 continue;
    23.             driver.AddFromName(iter.propertyPath);
    24.         }
    25. #endif
    26.         base.GatherProperties(director, driver);
    27.     }
    28. }
     
  2. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    In the CreateTrackMixer, the GameObject (go) contains the playableDirector. You can get the binding for the track, and pass it to the custom clip, then in the CreatePlayable method of the clip pass it to the custom playable.
     
    Rodolinc likes this.
  3. Rodolinc

    Rodolinc

    Joined:
    Sep 23, 2013
    Posts:
    63
    Thank you it worked.

    I took your previous post as an example.
     
  4. fwalker

    fwalker

    Joined:
    Feb 5, 2013
    Posts:
    255
    I am also hunting this down... I got the first couple of steps... "In the CreateTrackMixer, the GameObject (go) contains the playableDirector. You can get the binding for the track, and pass it to the custom clip" but I am stuck here...

    "then CreatePlayable method of the clip pass it to the custom playable" example?
    and how then do I get this reference in the actual call to public virtual void OnBehaviourPlay(Playable playable, FrameData info)

    Thanks
     
  5. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    Using the example above, here is how to go about it. The gameObject will then be available to all methods in the CustomPlayableBehaviour, except OnPlayableCreate().

    Note that the gameObject field in CustomPlayableBehaviour needs to public

    Code (CSharp):
    1. public class CustomPlayableTrack : TrackAsset
    2. {
    3.     public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount)
    4.     {
    5.        var binding = go.GetComponent<PlayableDirector>().GetGenericBinding(this) as GameObject;
    6.  
    7.         foreach (var c in GetClips())
    8.             ((CustomPlayableAsset)(c.asset)).gameObject = binding;
    9.  
    10.         return ScriptPlayable<CustomPlayableBehavior>.Create(graph, inputCount);
    11.     }
    12. ...
    13. }
    14.  
    15. public class CustomPlayableAsset : PlayableAsset
    16. {  
    17.     public bool toLoad;
    18.     public GameObject gameObject {get;set;}   // should be public and not serializable.
    19.  
    20.     public override Playable CreatePlayable(PlayableGraph graph, GameObject owner)
    21.     {
    22.         var playable = ScriptPlayable<CustomPlayableBehavior>.Create(graph);
    23.  
    24.         var scenePlayableBehavior = playable.GetBehaviour();
    25.         scenePlayableBehavior.toLoad = toLoad;
    26.         scenePlayableBehavior.gameObject = gameObject;
    27.         return playable;
    28.     }
    29. }