Пример #1
0
        //============================================================================================
        /**
        *  @brief Constructor for the MxMLayer class which takes a playable instead of an animation clip. 
        *  Sets up all initial values and creates the layer's mixer.
        *  
        *  @param [int] a_id - the layer id (lowest layer value is 2 for MxMLayers)
        *  @param [int] a_maxClips - the maximum number of clips that can be blended on this layer
        *  @param [ref PlayableGraph] a_playableGraph - the playable graph that this layer lives on
        *  @param [Playable] a_playable - the playable to use for this layer
        *  @param [AvatarMask] a_mask - the mask to use with this player (Default null)
        *  @param [float] a_weight - the starting weight of this layer (Default 0)
        *  @param [bool] a_additive - whether the layer is additive or not (Default false)
        *         
        *********************************************************************************************/
        public MxMLayer(int a_id, ref AnimationLayerMixerPlayable a_layerMixer,
           Playable a_playable, AvatarMask a_mask = null, float a_weight = 0f, bool a_additive = false)
        {
            if (!a_playable.IsValid())
                Debug.LogError("Error: Attempting to create an MxMLayer with an invalid playable");

            if (!a_layerMixer.IsValid())
                Debug.LogError("Error: Attempting to create an MxMLayer with an invalid layerMixer.");

            m_layerMixer = a_layerMixer;
            m_playableGraph = m_layerMixer.GetGraph();

            Id = a_id;

            PrimaryInputId = 0;
            MaxClips = 1;

            m_layerMixer.ConnectInput(Id, a_playable, 0);

            Mask = a_mask;

            m_layerMixer.SetLayerAdditive((uint)Id, a_additive);
            m_layerMixer.SetInputWeight(Id, Mathf.Clamp01(a_weight));

            SubLayerWeights = new float[1];
            SubLayerWeights[0] = 1f;
        }
Пример #2
0
        //============================================================================================
        /**
        *  @brief Constructor for the MxMLayer class. Sets up all initial values and creates the layer's
        *  mixer 
        *  
        *  @param [int] a_id - the layer id (lowest layer value is 2 for MxMLayers)
        *  @param [int] a_maxClips - the maximum number of clips that can be blended on this layer
        *  @param [ref PlayableGraph] a_playableGraph - the playable graph that this layer lives on
        *  @param [AnimationClip] a_clip - the starting animation clip to use for this layer.
        *  @param [AvatarMask] a_mask - the mask to use with this player (Default null)
        *  @param [float] a_weight - the starting weight of this layer (Default 0)
        *  @param [bool] a_additive - whether the layer is additive or not (Default false)
        *         
        *********************************************************************************************/
        public MxMLayer(int a_id, int a_maxClips, ref AnimationLayerMixerPlayable a_layerMixer, 
            AnimationClip a_clip, AvatarMask a_mask = null, float a_weight = 0f, bool a_additive = false)
        {
            Assert.IsNotNull(a_clip, "Error: Attempting to create an MxMLayer with null AnimationClip");

            if (!a_layerMixer.IsValid())
                Debug.LogError("Error: Attempting to create an MxMLayer with an invalid layerMixer.");

            m_playableGraph = a_layerMixer.GetGraph();
            m_layerMixer = a_layerMixer;
            PrimaryClip = a_clip;

            Id = a_id;
            MaxClips = a_maxClips;

            PrimaryInputId = 0;

            Mixer = AnimationMixerPlayable.Create(m_playableGraph, a_maxClips, true);
            var clipPlayable = AnimationClipPlayable.Create(m_playableGraph, PrimaryClip);

            m_layerMixer.ConnectInput(Id, Mixer, 0);

            Mixer.ConnectInput(0, clipPlayable, 0);
            Mixer.SetInputWeight(0, 1f);

            Mask = a_mask;

            m_layerMixer.SetLayerAdditive((uint)Id, a_additive);
            m_layerMixer.SetInputWeight(Id, Mathf.Clamp01(a_weight));

            SubLayerWeights = new float[MaxClips];
            SubLayerWeights[0] = 1f;
        }
Пример #3
0
        /// <summary>
        /// If the first state gets added after Initialize and InitializeLayerBlending has run, we disconnect and destroy the empty state mixer, and then
        /// re-initialize.
        /// </summary>
        private void HandleAddedFirstStateAfterStartup(AnimationPlayerState state, Dictionary <string, float> blendVariableValues)
        {
            states.Add(state);

            // layerMixer.IsValid => there's more than 1 layer.
            if (layerMixer.IsValid())
            {
                containingGraph.Disconnect(layerMixer, layerIndex);
            }

            stateMixer.Destroy();

            InitializeSelf(containingGraph, defaultTransition, clipSwapCollections, blendVariableValues);

            if (layerMixer.IsValid())
            {
                InitializeLayerBlending(containingGraph, layerIndex, layerMixer);
            }
        }
Пример #4
0
        void FindMixers()
        {
            m_Mixers.Clear();
            m_PoseMixer       = AnimationLayerMixerPlayable.Null;
            m_LayerMixer      = AnimationLayerMixerPlayable.Null;
            m_MotionXPlayable = AnimationMotionXToDeltaPlayable.Null;

            var playable   = m_Output.GetSourcePlayable();
            var outputPort = m_Output.GetSourceOutputPort();

            if (!playable.IsValid() || outputPort < 0 || outputPort >= playable.GetInputCount())
            {
                return;
            }

            var mixer = FindFirstAnimationPlayable(playable.GetInput(outputPort));

            Playable motionXPlayable = mixer;

            if (motionXPlayable.IsPlayableOfType <AnimationMotionXToDeltaPlayable>())
            {
                m_MotionXPlayable = (AnimationMotionXToDeltaPlayable)motionXPlayable;
                mixer             = m_MotionXPlayable.GetInput(0);
            }

#if UNITY_EDITOR
            // Default pose mixer
            if (!Application.isPlaying)
            {
                if (mixer.IsValid() && mixer.IsPlayableOfType <AnimationLayerMixerPlayable>())
                {
                    m_PoseMixer = (AnimationLayerMixerPlayable)mixer;
                    mixer       = m_PoseMixer.GetInput(1);
                }
            }
#endif

            // Track mixer
            if (mixer.IsValid() && mixer.IsPlayableOfType <AnimationLayerMixerPlayable>())
            {
                m_LayerMixer = (AnimationLayerMixerPlayable)mixer;
            }

            if (!m_LayerMixer.IsValid())
            {
                return;
            }

            var count = m_LayerMixer.GetInputCount();
            for (var i = 0; i < count; i++)
            {
                FindMixers(m_LayerMixer, i, m_LayerMixer.GetInput(i));
            }
        }
        void FindMixers()
        {
            m_Mixers.Clear();
            m_PoseMixer       = AnimationMixerPlayable.Null;
            m_LayerMixer      = AnimationLayerMixerPlayable.Null;
            m_MotionXPlayable = AnimationMotionXToDeltaPlayable.Null;

            var playable   = m_Output.GetSourcePlayable();
            var outputPort = m_Output.GetSourceOutputPort();

            if (!playable.IsValid() || outputPort < 0 || outputPort >= playable.GetInputCount())
            {
                return;
            }

            var mixer = FindFirstAnimationPlayable(playable.GetInput(outputPort));

            Playable motionXPlayable = mixer;

            if (motionXPlayable.IsPlayableOfType <AnimationMotionXToDeltaPlayable>())
            {
                m_MotionXPlayable = (AnimationMotionXToDeltaPlayable)motionXPlayable;
                mixer             = m_MotionXPlayable.GetInput(0);
            }

            if (mixer.IsValid() && mixer.IsPlayableOfType <AnimationMixerPlayable>())
            {
                m_PoseMixer = (AnimationMixerPlayable)mixer;
                Playable layerMixer = m_PoseMixer.GetInput(0);

                if (layerMixer.IsValid() && layerMixer.IsPlayableOfType <AnimationLayerMixerPlayable>())
                {
                    m_LayerMixer = (AnimationLayerMixerPlayable)layerMixer;
                }
            }
            else if (mixer.IsValid() && mixer.IsPlayableOfType <AnimationLayerMixerPlayable>())
            {
                m_LayerMixer = (AnimationLayerMixerPlayable)mixer;
            }


            if (!m_LayerMixer.IsValid())
            {
                return;
            }

            var count = m_LayerMixer.GetInputCount();

            for (var i = 0; i < count; i++)
            {
                FindMixers(m_LayerMixer, i, m_LayerMixer.GetInput(i));
            }
        }
Пример #6
0
        public static bool TryInjectMixer(this PlayableDirector dir, Playable timelinePlayable, Animator animator,
                                          out AnimationLayerMixerPlayable mixerPlayable)
        {
            mixerPlayable = AnimationLayerMixerPlayable.Null;

            if (timelinePlayable.IsValid() == false)
            {
                Debug.LogError("Timeline Playable is not valid");
                return(false);
            }

            if (!dir)
            {
                Debug.LogError("PlayableDirector is null");
                return(false);
            }

            if (!dir.playableAsset)
            {
                Debug.LogError("PlayableDirector has no TimelineAsset assigned", dir);
                return(false);
            }

            if (!animator)
            {
                Debug.LogError("Animator is null");
                return(false);
            }

            var tracks = new List <TrackAsset>();

            if (!TryGetTracks(dir, tracks))
            {
                Debug.LogError("No AnimationTracks found", dir);
                return(false);
            }

            var animatorIndex = 0;
            var found         = false;

            // try find the timeline graph index for this animator
            // we do this by looping bindings for all animation tracks
            // and check if the binding maps to the animator we want to inject a mixer for
            foreach (var track in tracks)
            {
                if (found)
                {
                    break;
                }
                if (track.isEmpty || track.muted || !track.hasClips)
                {
                    continue;
                }
                var trackOutputs = track.outputs;
                foreach (var to in trackOutputs)
                {
                    var trackBinding = dir.GetGenericBinding(to.sourceObject);
                    if (trackBinding && trackBinding == animator)
                    {
                        found = true;
                        break;
                    }

                    animatorIndex++;
                }
            }

            if (!found)
            {
                Debug.LogWarning("Animator " + animator + " is not bound to " + dir, dir);
                return(false);
            }

            if (PrintDebugInfo)
            {
                Debug.Log("found: " + animatorIndex);
            }

            var playable   = timelinePlayable.GetInput(animatorIndex);
            var prevOutput = playable.GetOutput(0);
            var prevInput  = prevOutput.GetInput(animatorIndex);

            // Debug.Log(prevOutput.GetPlayableType() + ", " + prevInput.GetPlayableType());
            // return false;
            mixerPlayable = AnimationLayerMixerPlayable.Create(dir.playableGraph, 1);
            // var pWeight = o.GetInputWeight(0);
            prevOutput.DisconnectInput(animatorIndex);
            prevOutput.ConnectInput(animatorIndex, mixerPlayable, 0);
            mixerPlayable.ConnectInput(0, prevInput, 0, 1);
            return(mixerPlayable.IsValid());
        }