Search Unity

How to set value fields in CustomPlayableBehavior at runtime?

Discussion in 'Timeline' started by fastgamedev, Jun 10, 2017.

  1. fastgamedev

    fastgamedev

    Joined:
    Mar 27, 2014
    Posts:
    91
    I have this code:

    Code (CSharp):
    1. public class ScrollNumbersPlayable : BasicPlayableBehaviour {    
    2.     public float startingNumber;
    3.     public float endingNumber;
    4. ....
    5. }
    Couple of questions:
    1. How do I set the value of startingNumber from another script at runtime? (There can be multiple such clips on one track).
    2. How can I set things up in such a way that a game designer using the editor, without accessing the code, can hookup the value of startingNumber to be read from another component that exposes it?

    Basically, what are the best practices for data binding of custom timeline playables?
     
  2. julienb

    julienb

    Unity Technologies

    Joined:
    Sep 9, 2016
    Posts:
    123
    One way to acheive what you want to do is by using exposed references. Your custom PlayableAsset can have a reference to a GameObject, a Component or an asset. It can then use that reference to build a PlayableBehaviour. Here's an example:
    Code (CSharp):
    1. public class MyPlayableAsset : PlayableAsset
    2. {
    3.     public ExposedReference<Transform> transformReference;
    4.  
    5.     public override Playable CreatePlayable(PlayableGraph graph, GameObject go) {
    6.         var playable = ScriptPlayable<MyPlayableBehaviour>.Create(graph);
    7.         var scale = transformReference.Resolve(graph.GetResolver()).localScale;
    8.         if (scale != null)
    9.             playable.GetBehaviour().Initialize(scale);
    10.         return playable;
    11.     }
    12. }
    13.  
    14. public class MyPlayableBehaviour : PlayableBehaviour
    15. {
    16.     Vector3 scale { get; set;}
    17.     public void Initialize(Vector3 aScale)
    18.     {
    19.         scale = aScale;
    20.     }
    21.  
    22.     public void PrepareFrame(Playable playable, FrameData info)
    23.     {
    24.         //Do something with scale;
    25.     }
    26. }
    You can use MyPlayableAsset on a PlayableTrack. A game designer will then be able to drop a Transform component on the clip in the timeline.


    Warning: At runtime, once a PlayableDirector is playing, changing values in PlayableAssets will have no effect. You will need to stop and then play the PlayableDirector to refresh.
     
  3. fastgamedev

    fastgamedev

    Joined:
    Mar 27, 2014
    Posts:
    91
    Thank you.

    So are you saying that whenever I have some custom data to reference in a PlayableAsset, I need to create a custom data class? Eg:

    Code (CSharp):
    1. public class ScrollNumbersData : MonoBehaviour {
    2.   public float startingNumber;
    3.   public float endingNumber;
    4. }
    5.  
    6. public class ScrollNumbersPlayable : BasicPlayableBehaviour {  
    7.   public ExposedReference<ScrollNumbersData> data;
    8. ....
    9. }
     
  4. julienb

    julienb

    Unity Technologies

    Joined:
    Sep 9, 2016
    Posts:
    123
    Yes, you will have to write a custom component in that case.

    Also, I would suggest that you use PlayableAsset and PlayableBehaviour instead of BasicPlayableBehaviour. Having a PlayableAsset/PlayableBehaviour pair is the preferred way, since BasicPlayableBehaviour is more costly on performance. The exposed references normally go into a PlayableAsset, since it contains the data necessary for your PlayableBehaviour to function. The PlayableAsset will then be used to create a PlayableBehaviour. That’s why they normally they come in pairs.
     
    ModLunar likes this.
  5. fastgamedev

    fastgamedev

    Joined:
    Mar 27, 2014
    Posts:
    91