Search Unity

  1. Unity 2019.1 is now released.
    Dismiss Notice

How to make custom playables reset to previous state after preview

Discussion in 'Timeline' started by Yukken, Apr 24, 2019.

  1. Yukken

    Yukken

    Joined:
    Jul 12, 2015
    Posts:
    35
    I made a custom playable that advances the dialogue once per clip.When I preview the timeline in edit mode, it works but the changes persist after exiting preview. Is this expected behavior? If not, How to fix it so that the state of the dialogue track is reset when preview ends?

    Here is the behaviour class for the clip. It simply calls a function to advance the text on the linesource once in it' lifetime.
    Code (CSharp):
    1. using System;
    2. using UnityEngine;
    3. using UnityEngine.Playables;
    4. using UnityEngine.Timeline;
    5.  
    6. [Serializable]
    7. public class DialogueTrackBehaviour : PlayableBehaviour
    8. {
    9.     bool hasBegun = false;
    10.  
    11.     public override void OnPlayableCreate(Playable playable)
    12.     {
    13.  
    14.     }
    15.  
    16.     public override void ProcessFrame(Playable playable, FrameData info, object playerData)
    17.     {
    18.         if (!hasBegun)
    19.         {
    20.             LineStream lineSource = playerData as LineStream;
    21.             hasBegun = true;
    22.             lineSource.advanceText();
    23.         }
    24.     }
    25. }
    26.  
     
  2. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    842
    You can tell timeline which properties you intend to modify using the IPropertyPreview interface.

    For example:
    Code (CSharp):
    1. public class TestCustomClip : PlayableAsset, IPropertyPreview
    2. {
    3.     ....
    4.     public void GatherProperties(PlayableDirector director, IPropertyCollector driver)
    5.     {
    6.         const string kLocalPosition = "m_LocalPosition";
    7.         const string kLocalRotation = "m_LocalRotation";
    8.  
    9.         driver.AddFromName<Transform>(kLocalPosition + ".x");
    10.         driver.AddFromName<Transform>(kLocalPosition + ".y");
    11.         driver.AddFromName<Transform>(kLocalPosition + ".z");
    12.         driver.AddFromName<Transform>(kLocalRotation + ".x");
    13.         driver.AddFromName<Transform>(kLocalRotation + ".y");
    14.         driver.AddFromName<Transform>(kLocalRotation + ".z");
    15.         driver.AddFromName<Transform>(kLocalRotation + ".w");
    16.     }
    17.     ...
    18. }
    In your case, driver.AddFromName<LineStream>("variableName"); where variableName is the name of the serialized property (i.e. the field) in the LineStream that is being modified by advanceText();
     
  3. Yukken

    Yukken

    Joined:
    Jul 12, 2015
    Posts:
    35
    Uh I'm not very familar with reflection. I just used the playabes wizard to generate most of the code and modified it to my understanding. In my case advancetext() does not directly modify properties of line stream. The linestream class has a list of strings for dialogue, an int field for index and a text gameobject ref. The advancetext() function increments the index and sets the text to the next string in the list.
    Is this incompatible with playables?
     
    Last edited: Apr 24, 2019
  4. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    842
    No reflection required. Which ever fields in the monobehaviour are serialized.

    e.g. if your class looks like this

    public class SampleMonoBehaviour : Monobehaviour
    {
    public int index;
    public string text;
    ....

    }

    Your GatherProperties code would be
    ...
    driver.AddFromName<SampleMonoBehaviour>("index");
    driver.AddFromName<SampleMonoBehaviour>("text");

    It does get more complicated when you target built-in Unity Components, but for your own Monobehaviours, it is pretty straight forward.
     
  5. Yukken

    Yukken

    Joined:
    Jul 12, 2015
    Posts:
    35
    Does a textmeshpro field count as built in unity component?
     
  6. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    842
    If the field exists in your monobehaviour, you can just use the name of the field without a problem even if it refers to a Unity type.

    The only time it gets tricky is when your track binds to a Unity Type (TextMeshPro might count here) because it's tricky to know which of it's fields are actually serialized, or what their names are.