Search Unity

Set TimelineClip.(pre|post)ExtrapolationMode from Script

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

  1. dseyb

    dseyb

    Joined:
    Jan 24, 2014
    Posts:
    9
    Hi everyone,

    I am creating TimelineClips in code via TimelineTrack.CreateDefaultClip(). I'd like to set the extrapolation modes on those clips but I cannot do that, because the setters for those are internal.
    It seems you can set it via the Inspector only because the corresponding private fields are marked with [SerializeField].
    Is there any way to set theses values that's not reflection?

    Cheers, Dario
     
  2. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,010
    Unfortunately, no. This is an oversight in the API - we've logged it as an item to address in our product backlog.
     
  3. panta

    panta

    Joined:
    Aug 10, 2012
    Posts:
    71
    Will this feature be coming in 2018.3? It would be really nice to be able to set this from script
     
    kogtech7 likes this.
  4. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,010
    Probably not, but we will try to bump the priority and get it for 2019.1.
     
  5. panta

    panta

    Joined:
    Aug 10, 2012
    Posts:
    71
    no worries

    if anyone needs it, here are some extension methods that will work with 2018.2 (tested in Editor and iOS):
    Code (CSharp):
    1.    
    2.     /// <summary>
    3.     /// Private field name of <see cref="TimelineClip.postExtrapolationMode"/>
    4.     /// </summary>
    5.     private static readonly string POST_EXTRAP_MODE_INTERNAL_FIELD = "m_PostExtrapolationMode";
    6.  
    7.     /// <summary>
    8.     /// Private field name of <see cref="TimelineClip.preExtrapolationMode"/>
    9.     /// </summary>
    10.     private static readonly string PRE_EXTRAP_MODE_INTERNAL_FIELD = "m_PreExtrapolationMode";
    11.  
    12.     /// <summary>
    13.     /// Private field name of the "Animation Extrapolation" duration beyond the end of the clip
    14.     /// </summary>
    15.     private static readonly string POST_EXTRAP_TIME_INTERNAL_FIELD = "m_PostExtrapolationTime";
    16.  
    17.     /// <summary>
    18.     /// Private field name of the "Animation Extrapolation" duration before the start of the clip
    19.     /// </summary>
    20.     private static readonly string PRE_EXTRAP_TIME_INTERNAL_FIELD = "m_PreExtrapolationTime";  
    21.  
    22.     /// <summary>
    23.     /// Sets the pre-extrapolation mode for a clip
    24.     /// (uses Unity 2018.2.0f2 internal methods that may break in future versions)
    25.     /// </summary>
    26.     /// <param name="clip">Clip to set the extrapolation for</param>
    27.     /// <param name="extrapolationMode">Extrapolation behaviour</param>
    28.     public static void SetPreExtrapolationMode(this TimelineClip clip, TimelineClip.ClipExtrapolation extrapolationMode)
    29.     {
    30.         clip.SetPrivateFieldValue<TimelineClip.ClipExtrapolation>(PRE_EXTRAP_MODE_INTERNAL_FIELD, extrapolationMode);
    31.     }
    32.  
    33.     /// <summary>
    34.     /// Sets the pre-extrapolation time for a clip (duration of the extrapolated portion)
    35.     /// (uses Unity 2018.2.0f2 internal methods that may break in future versions)
    36.     /// </summary>
    37.     /// <param name="clip">Clip to set the extrapolation for</param>
    38.     /// <param name="time">How long to extrapolate into the past before the clip starts</param>
    39.     public static void SetPreExtrapolationTime(this TimelineClip clip, double time)
    40.     {
    41.         clip.SetPrivateFieldValue<double>(PRE_EXTRAP_TIME_INTERNAL_FIELD, time);
    42.     }
    43.  
    44.     /// <summary>
    45.     /// Gets the pre-extrapolation time for a clip (duration of the extrapolated portion)
    46.     /// (uses Unity 2018.2.0f2 internal methods that may break in future versions)
    47.     /// </summary>
    48.     /// <param name="clip">Clip to get the extrapolation for</param>
    49.     /// <param name="time">Duration of the extrapolation into the past before the clip starts</param>
    50.     public static double GetPreExtrapolationTime(this TimelineClip clip)
    51.     {
    52.         return clip.GetPrivateFieldValue<double>(PRE_EXTRAP_TIME_INTERNAL_FIELD);
    53.     }
    54.  
    55.     /// <summary>
    56.     /// Sets the post-extrapolation mode for a clip
    57.     /// (uses Unity 2018.2.0f2 internal methods that may break in future versions)
    58.     /// </summary>
    59.     /// <param name="clip">Clip to set the extrapolation for</param>
    60.     /// <param name="extrapolationMode">Extrapolation behaviour</param>
    61.     public static void SetPostExtrapolationMode(this TimelineClip clip, TimelineClip.ClipExtrapolation extrapolationMode)
    62.     {
    63.         clip.SetPrivateFieldValue<TimelineClip.ClipExtrapolation>(POST_EXTRAP_MODE_INTERNAL_FIELD, extrapolationMode);
    64.     }
    65.  
    66.     /// <summary>
    67.     /// Sets the post-extrapolation time for a clip (duration of the extrapolated portion)
    68.     /// (uses Unity 2018.2.0f2 internal methods that may break in future versions)
    69.     /// </summary>
    70.     /// <param name="clip">Clip to set the extrapolation for</param>
    71.     /// <param name="time">How long to extrapolate into the future beyond the clip end</param>
    72.     public static void SetPostExtrapolationTime(this TimelineClip clip, double time)
    73.     {
    74.         clip.SetPrivateFieldValue<double>(POST_EXTRAP_TIME_INTERNAL_FIELD, time);
    75.     }
    76.  
    77.     /// <summary>
    78.     /// Gets the post-extrapolation time for a clip (duration of the extrapolated portion)
    79.     /// (uses Unity 2018.2.0f2 internal methods that may break in future versions)
    80.     /// </summary>
    81.     /// <param name="clip">Clip to get the extrapolation for</param>
    82.     /// <param name="time">Duration of the extrapolation into the future beyond the clip end</param>
    83.     public static double GetPostExtrapolationTime(this TimelineClip clip)
    84.     {
    85.         return clip.GetPrivateFieldValue<double>(POST_EXTRAP_TIME_INTERNAL_FIELD);
    86.     }
    87.  
    88.  
    89.  
    90.     /// <summary>
    91.     /// Returns a private Property Value from a given Object. Uses Reflection.
    92.     /// Throws a ArgumentOutOfRangeException if the Property is not found.
    93.     /// </summary>
    94.     /// <typeparam name="T">Type of the Property</typeparam>
    95.     /// <param name="obj">Object from where the Property Value is returned</param>
    96.     /// <param name="propName">Propertyname as string.</param>
    97.     /// <returns>PropertyValue</returns>
    98.     public static T GetPrivateFieldValue<T>(this object obj, string propName)
    99.     {
    100.         if (obj == null) throw new ArgumentNullException("obj");
    101.         Type t = obj.GetType();
    102.         FieldInfo fi = null;
    103.         while (fi == null && t != null)
    104.         {
    105.             fi = t.GetField(propName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
    106.             t = t.BaseType;
    107.         }
    108.         if (fi == null) throw new ArgumentOutOfRangeException("propName", string.Format("Field {0} was not found in Type {1}", propName, obj.GetType().FullName));
    109.         return (T)fi.GetValue(obj);
    110.     }
    111.  
    112.     /// <summary>
    113.     /// Set a private Property Value on a given Object. Uses Reflection.
    114.     /// </summary>
    115.     /// <typeparam name="T">Type of the Property</typeparam>
    116.     /// <param name="obj">Object from where the Property Value is returned</param>
    117.     /// <param name="propName">Propertyname as string.</param>
    118.     /// <param name="val">the value to set</param>
    119.     /// <exception cref="ArgumentOutOfRangeException">if the Property is not found</exception>
    120.     public static void SetPrivateFieldValue<T>(this object obj, string propName, T val)
    121.     {
    122.         if (obj == null) throw new ArgumentNullException("obj");
    123.         Type t = obj.GetType();
    124.         FieldInfo fi = null;
    125.         while (fi == null && t != null)
    126.         {
    127.             fi = t.GetField(propName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
    128.             t = t.BaseType;
    129.         }
    130.         if (fi == null) throw new ArgumentOutOfRangeException("propName", string.Format("Field {0} was not found in Type {1}", propName, obj.GetType().FullName));
    131.         fi.SetValue(obj, val);
    132.     }
     
    senkal_ and seant_unity like this.
  6. kogtech7

    kogtech7

    Joined:
    Jul 31, 2017
    Posts:
    7
    Seems this didn't make the cut for 2019.1. Just a hopeful bump for 2019.2!
     
  7. ShervinM

    ShervinM

    Joined:
    Sep 16, 2017
    Posts:
    21
    Any news on this? :(
     
  8. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,010
    Sorry, not yet.