public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount)
    {
        if (_mTrackBinding == null)
        {
            BlendShapeController trackBinding = go.GetComponent <PlayableDirector>().GetGenericBinding(this) as BlendShapeController;
            _mTrackBinding = trackBinding;
        }
        //iterator for all currently existing clips
        IEnumerable <TimelineClip> clips = GetClips();

        //check if track binding has been set
        if (_mTrackBinding != null)
        {
            List <string> clipGuids = new List <string>();
            //check each clip
            foreach (var item in clips)
            {
                //rename clip if not customized by user
                if (item.displayName == "BlendShapeControlClip")
                {
                    item.displayName = _mTrackBinding.transform.root.name + " " + _mTrackBinding.name;
                }

                //get blendShapeControlClip encapulated in TimelineClip
                BlendShapeControlClip blendShapeControlClip = item.asset as BlendShapeControlClip;

                //get BlendShapeControlBehaviour encapulated in BlendShapeControlClip
                BlendShapeControlBehaviour blendShapeControlBehaviour = blendShapeControlClip.template;

                //check just in case there aren't any blendshapes on the attached controller
                if (_mTrackBinding.blendShapeTargets.Length > 0)
                {
                    //update  blendShapeTargets from _mTrackBinding to BlendShapeController
                    clipGuids.Add(blendShapeControlBehaviour.LoadBlendShapeTargets(_mTrackBinding.blendShapeTargets, clipGuids));
                }
                //this is just informational so the inmspector will make it clear what object is being edited
                blendShapeControlBehaviour.name = _mTrackBinding.transform.root.name + " " + _mTrackBinding.name;
            }
        }
        return(ScriptPlayable <BlendShapeControlMixerBehaviour> .Create(graph, inputCount));
    }
    public override void ProcessFrame(Playable playable, FrameData info, object playerData)
    {
        //     Debug.Log(" Mixer ProcessFrame");
        m_TrackBinding = playerData as BlendShapeController;

        if (m_TrackBinding == null)
        {
            return;
        }

        if (!m_FirstFrameHappened)
        {
            m_FirstFrameHappened = true;

            if (m_TrackBinding.blendShapeTargets != null && m_TrackBinding.blendShapeTargets.Length > 0)
            {
                blendShapeDefaults = new float[m_TrackBinding.blendShapeTargets.Length];

                for (int i = 0; i < m_TrackBinding.blendShapeTargets.Length; i++)
                {
                    blendShapeDefaults[i] = m_TrackBinding.blendShapeTargets[i].BlendShapeDefaultValue;
                }
            }
        }

        int inputCount = playable.GetInputCount();

        float[] blendShapeWeights = new float[m_TrackBinding.blendShapeTargets.Length];

        float totalWeight    = 0f;
        float greatestWeight = 0f;
        int   currentInputs  = 0;

        for (int i = 0; i < inputCount; i++)
        {
            float inputWeight = playable.GetInputWeight(i);
            ScriptPlayable <BlendShapeControlBehaviour> inputPlayable = (ScriptPlayable <BlendShapeControlBehaviour>)playable.GetInput(i);
            BlendShapeControlBehaviour input = inputPlayable.GetBehaviour();


            if (blendShapeWeights.Length > 0 && input.blendShapeKeys != null && input.blendShapeKeys.Length == blendShapeWeights.Length)
            {
                for (int j = 0; j < blendShapeWeights.Length; j++)
                {
                    blendShapeWeights[j] += input.blendShapeKeys[j].BlendShapeValue * inputWeight;
                }
            }
            totalWeight += inputWeight;

            if (inputWeight > greatestWeight)
            {
                greatestWeight = inputWeight;
            }

            if (!Mathf.Approximately(inputWeight, 0f))
            {
                currentInputs++;
            }
        }
        float remainingweight = 1 - totalWeight;

        for (int i = 0; i < blendShapeWeights.Length; i++)
        {
            blendShapeWeights[i] += blendShapeDefaults[i] * remainingweight;
        }

        m_TrackBinding.SetBlendShapeValues(blendShapeWeights);
    }