Search Unity

Animation of multiple component instances not possible. Bug?

Discussion in 'Timeline' started by snw, Dec 19, 2018.

  1. snw

    snw

    Joined:
    Mar 13, 2014
    Posts:
    42
    Hi,

    I have the following scenario:
    • Two component instances are attached to the same GameObject.
    • Each of these have their properties set differently (see "Mat" property) components.jpg
    • I now need to animate the "Reveal" property of the two components independently via Timeline

    Result:
    As long as I keyframe only one component, everything works ok. As soon as I animate the second component (by using a second Animation track) nothing animates at all anymore. If I mute the second Animation track, the animation for the first component works again.

    Why is that? And how can I achieve the desired behaviour, preferably without adding another GameObject for the second component instance?

    P.S: I originally had only one component controlling both materials. This worked but proved to be too inflexibel.


    Thanks
     
  2. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    I think this is a limitation of the animation system, I don't think it handles multiple components of the same type.

    Alternately you can write a custom track with a UI Material Animator as a track binding, a clip with a reveal float and a mixer which assigns it. The advantage being the binding can distinguish which component you are animating.

    The clips parameter will be animatable.

    Here's an example (note the track and the clip must exist in files with the same name as the class):

    Code (CSharp):
    1. [System.Serializable]
    2. public class UIMaterialClipBehaviour : PlayableBehaviour
    3. {
    4.     public float reveal;
    5. }
    6.  
    7. public class UIMaterialMixer : PlayableBehaviour
    8. {
    9.     public override void ProcessFrame(Playable playable, FrameData info, object playerData)
    10.     {
    11.         float finalReveal = 0;
    12.         for (int i = 0; i < playable.GetInputCount(); i++)
    13.         {
    14.             var clip = (ScriptPlayable<UIMaterialClipBehaviour>) (playable.GetInput(i));
    15.             var behaviour = clip.GetBehaviour();
    16.             finalReveal += behaviour.reveal * playable.GetInputWeight(i);
    17.         }
    18.  
    19.         UIMaterialAnimator animator = (UIMaterialAnimator) playerData;
    20.         if (animator)
    21.             animator.reveal = finalReveal;
    22.     }
    23. }
    24.  
    25. [TrackBindingType(typeof(UIMaterialAnimator))]
    26. [TrackClipType(typeof(UIMaterialClip))]
    27. public class UIMaterialAnimatorTrack : TrackAsset
    28. {
    29.     public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount)
    30.     {
    31.         return ScriptPlayable<UIMaterialMixer>.Create(graph);
    32.     }
    33. }
    34.  
    35.  
    36. public class UIMaterialClip : PlayableAsset, IPropertyPreview
    37. {
    38.     public UIMaterialClipBehaviour template;
    39.     public override Playable CreatePlayable(PlayableGraph graph, GameObject owner)
    40.     {
    41.         return ScriptPlayable<UIMaterialClipBehaviour>.Create(graph, template);
    42.     }
    43.     public void GatherProperties(PlayableDirector director, IPropertyCollector driver)
    44.     {
    45.         driver.AddFromName<UIMaterialAnimator>("reveal");
    46.     }
    47. }
     
  3. snw

    snw

    Joined:
    Mar 13, 2014
    Posts:
    42
    Ok, thanks.

    Do you know if there are plans to fix this limitation? The current behaviour seems to be quite unintuitive and confusing.
     
    IgorArnaut, customphase and Enderlook like this.