Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

Problems Adding AnimationClipPlayable when using Timeline

Discussion in 'Timeline' started by UnityChenYi, Mar 2, 2018.

  1. UnityChenYi

    UnityChenYi

    Joined:
    Jun 23, 2017
    Posts:
    2
    OK, it's my first time to create thread in Unity Forums, and my mother tongue is not English. If any annoying or confusing, I'm very sorry.

    Unity Version: 2017.3.0f3

    I want to add an AnimationClip for a GameObject when using Timeline which already has a Animation Track. So I use AnimationClipPlayable.Create, AnimationLayerMixerPlayable.AddInput, and AnimationLayerMixerPlayable.SetLayerMaskFromAvatarMask. The following is my code:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Animations;
    5. using UnityEngine.Playables;
    6. using System;
    7.  
    8. public class TimelineLayerMixerPlayable : MonoBehaviour
    9. {
    10.     public AnimationClip AdditionClip0;
    11.     public AnimationClip AdditionClip1;
    12.  
    13.     public Transform MaskTransform;
    14.     public AvatarMask mask;
    15.  
    16.     [Range(0.0f, 1.0f)]
    17.     public float Weight = 1.0f;
    18.  
    19.     private PlayableGraph m_Graph;
    20.     private AnimationLayerMixerPlayable m_Mixer;
    21.  
    22.     private Playable srcPlayable;
    23.     private AnimationClip srcClip;
    24.  
    25.     private const int srcInputIndex = 0;
    26.     private const int addInputIndex = 1;
    27.     // Use this for initialization
    28.     void Start()
    29.     {
    30.         m_Graph = GetComponent<PlayableDirector>().playableGraph;
    31.         m_Mixer = FindLayerMixer(m_Graph);
    32.  
    33.         Debug.Log(m_Mixer.IsValid());
    34.  
    35.         int count = m_Graph.GetOutputCountByType<AnimationPlayableOutput>();
    36.         if (count > 1)
    37.         {
    38.             Debug.Log("too many animation outputs");
    39.             return;
    40.         }
    41.  
    42.         if (!mask)
    43.         {
    44.             mask = new AvatarMask();
    45.             mask.AddTransformPath(MaskTransform);
    46.         }
    47.  
    48.         MixAnimation(AdditionClip0);
    49.  
    50.         m_Graph.Play();
    51.     }
    52.  
    53.     // Update is called once per frame
    54.     void Update()
    55.     {
    56.         if (m_Mixer.IsValid() && m_Mixer.GetInputCount() > 1)
    57.         {
    58.             m_Mixer.SetInputWeight(addInputIndex, Weight);
    59.  
    60.             Playable addtionalAnim = m_Mixer.GetInput(addInputIndex);
    61.             if (addtionalAnim.GetTime() >= addtionalAnim.GetDuration())
    62.                 addtionalAnim.SetTime(0);
    63.         }
    64.  
    65.         if (Input.GetKeyUp(KeyCode.Space))
    66.         {
    67.             m_Mixer.SetInputCount(1);
    68.         }
    69.         else if (Input.GetKeyUp(KeyCode.Q))
    70.         {
    71.             MixAnimation(AdditionClip0);
    72.         }
    73.         else if (Input.GetKeyUp(KeyCode.W))
    74.         {
    75.             MixAnimation(AdditionClip1);
    76.         }
    77.     }
    78.  
    79.     private void MixAnimation(AnimationClip clip)
    80.     {
    81.         m_Mixer.SetInputCount(1);
    82.  
    83.         AnimationClipPlayable clipPlayable = AnimationClipPlayable.Create(m_Graph, clip);
    84.         clipPlayable.SetDuration(clip.length);
    85.  
    86.         m_Mixer.AddInput(clipPlayable, 0, Weight);
    87.         m_Mixer.SetLayerMaskFromAvatarMask(addInputIndex, mask);
    88.     }
    89.  
    90.     private AnimationLayerMixerPlayable FindLayerMixer(PlayableGraph graph)
    91.     {
    92.         PlayableOutput output = graph.GetOutputByType<AnimationPlayableOutput>(0);
    93.         Playable playable = output.GetSourcePlayable();
    94.  
    95.         return (AnimationLayerMixerPlayable)FindPlayableDFS<AnimationLayerMixerPlayable>(playable);
    96.     }
    97.  
    98.     private Playable FindPlayableDFS<T>(Playable playable) where T : IPlayable
    99.     {
    100.         if (playable.IsValid())
    101.         {
    102.             Type type = playable.GetPlayableType();
    103.  
    104.             if (type.Equals(typeof(T)))
    105.                 return playable;
    106.  
    107.             int inputCount = playable.GetInputCount();
    108.             for (int i = 0; i < inputCount; ++i)
    109.             {
    110.                 Playable res = FindPlayableDFS<T>(playable.GetInput(i));
    111.  
    112.                 if (res.IsValid())
    113.                     return res;
    114.             }
    115.         }
    116.         return Playable.Null;
    117.     }
    118. }
    When there is only the Animation Track in Timeline, or Animation Track is the first track in Timeline, everything is alright. I can mix, switch and disconnect the AnimationClip. However, when other tracks exist in Timeline, Activation Track for example, and the Animation Track is not the first track, something wrong occurs. Mixing still works, but only in Start phrase, which means when I press KeyCode.W, only animation in Timeline is visible. By the way, pressing KeyCode.Q still makes the original mix result work.

    When I look into PlayableGraph Visualizer, all seems to be right. AnimationClipPlayable is added to the correct place, saying, AnimationLayerMixerPlayable in the Graph, and is playing. I have printed some messages in AnimationClipPlayable, where there is the clip I want.

    Using some screenshot to describe the situations:

    The situation where everything is right:

    Timeline
    upload_2018-3-2_10-48-29.png

    PlayableGraph Before Playing
    upload_2018-3-2_10-21-37.png

    PlayableGraph After Playing


    The situation where something is wrong:

    Timeline
    upload_2018-3-2_10-35-3.png

    Due to number limitation of file uploading, PlayableGraph Before Playing is ignored here.

    PlayableGraph After Playing
    upload_2018-3-2_10-39-6.png

    I wonder whether there's something wrong in my codes, or it's a bug in Timeline or PlayableGraph.

    Related question:
    https://forum.unity.com/threads/problems-mixing-timeline-playables.496259/

    Hope for any answer. Thanks very much.
     

    Attached Files:

  2. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,003
    This sounded familiar so I did some digging, and there looks to be a fix for this issue in the upcoming 2018.1 release. We will look at backporting the fix to a patch in 2017.3.
     
  3. UnityChenYi

    UnityChenYi

    Joined:
    Jun 23, 2017
    Posts:
    2
    Thanks you very much. I'm looking forward to new release or the patch.