示例#1
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;
        }
示例#2
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;
        }
示例#3
0
        private void Play(AnimationClip animClip)
        {
            m_Graph = PlayableGraph.Create(name + " Character Anims");
            m_Graph.SetTimeUpdateMode(DirectorUpdateMode.GameTime);

            // Create the starting animation clip.
            AnimationClipPlayable animPlayable = AnimationClipPlayable.Create(m_Graph, animClip);

            // Create the transition mixer for changing animations over time.
            AnimationMixerPlayable transitionMixer = AnimationMixerPlayable.Create(m_Graph, 2);

            // Connect the base clip to the transition mixer.
            m_Graph.Connect(animPlayable, 0, transitionMixer, 1);

            transitionMixer.SetInputWeight(0, 0);
            transitionMixer.SetInputWeight(1, 1);

            // Create the layer output to handle 'heels'/'barefoot' options.
            AnimationPlayableOutput     playableOutput = AnimationPlayableOutput.Create(m_Graph, "LayerMixer", m_Animator);
            AnimationLayerMixerPlayable layerMixer     = AnimationLayerMixerPlayable.Create(m_Graph, 2);

            // Set the 'heels' layer to additive.
            layerMixer.SetLayerAdditive(1, true);
            playableOutput.SetSourcePlayable(layerMixer);

            layerMixer.ConnectInput(0, transitionMixer, 0, 1);

            m_Graph.Play();
        }
        /// <summary>
        /// Called by Unity.
        /// </summary>
        private void OnEnable()
        {
            _cubismFadeMotionList = GetComponent <CubismFadeController>().CubismFadeMotionList;

            // Fail silently...
            if (_cubismFadeMotionList == null)
            {
                Debug.LogError("CubismMotionController : CubismFadeMotionList doesn't set in CubismFadeController.");
                return;
            }

            // Get Animator.
            var animator = GetComponent <Animator>();

            if (animator.runtimeAnimatorController != null)
            {
                Debug.LogWarning("Animator Controller was set in Animator component.");
                return;
            }

            _isActive = true;

            // Disabble animator's playablegrap.
            var graph = animator.playableGraph;

            if (graph.IsValid())
            {
                graph.GetOutput(0).SetWeight(0);
            }

            // Create Playable Graph.
            _playableGrap = PlayableGraph.Create("Playable Graph : " + this.FindCubismModel().name);
            _playableGrap.SetTimeUpdateMode(DirectorUpdateMode.GameTime);

            // Create Playable Output.
            _playableOutput = AnimationPlayableOutput.Create(_playableGrap, "Animation", animator);
            _playableOutput.SetWeight(1);

            // Create animation layer mixer.
            _layerMixer = AnimationLayerMixerPlayable.Create(_playableGrap, LayerCount);

            // Create cubism motion layers.
            if (_motionLayers == null)
            {
                LayerCount    = (LayerCount < 1) ? 1 : LayerCount;
                _motionLayers = new CubismMotionLayer[LayerCount];
            }

            for (var i = 0; i < LayerCount; ++i)
            {
                _motionLayers[i] = CubismMotionLayer.CreateCubismMotionLayer(_playableGrap, _cubismFadeMotionList);
                _motionLayers[i].AnimationEndHandler += OnAnimationEnd;
                _layerMixer.ConnectInput(i, _motionLayers[i].PlayableOutput, 0);
                _layerMixer.SetInputWeight(i, 1.0f);
            }

            // Set Playable Output.
            _playableOutput.SetSourcePlayable(_layerMixer);
        }
示例#5
0
            public Instance(AnimStateController controller, PlayableGraph graph, AnimGraphSquash settings)
            {
                m_Settings = settings;

                m_AnimState      = controller.GetComponent <AnimStateData>();
                m_PredictedState = controller.GetComponent <LogicStateData>();

                m_Mixer = AnimationLayerMixerPlayable.Create(graph, 2);

                m_AnimSquash = AnimationClipPlayable.Create(graph, settings.animSquash);
                m_AnimSquash.SetApplyFootIK(false);
                m_AnimSquash.SetDuration(settings.animSquash.length);
                m_AnimSquash.Pause();

                m_Mixer.ConnectInput(1, m_AnimSquash, 0, 0.0f);
                m_Mixer.SetLayerAdditive(1, true);
            }
示例#6
0
    //============================================================================================================

    //モーションを再生する
    public bool play(AnimationClip clip, MotionPlayerParam param)
    {
        if (clip == null || param == null)
        {
            return(false);
        }

        MotionMixer motionMixer = motionMixers[param.layer];

        motionMixer.playParam = param;

        //切断
        graph.Disconnect(layerMixer, param.layer);

        //再接続
        motionMixer.reconnect(clip);
        layerMixer.ConnectInput(param.layer, motionMixer.mixer, sourceOutputIndex: 0, weight: 1f);

        //出力
        output.SetSourcePlayable(layerMixer);

        return(true);
    }
示例#7
0
        private void RebuildGraph(Animator animator)
        {
            DestroyGraph();

            m_Graph = PlayableGraph.Create("PreviewGraph");
            m_Graph.SetTimeUpdateMode(DirectorUpdateMode.Manual);

            m_ClipPlayable = AnimationClipPlayable.Create(m_Graph, state.activeAnimationClip);
            m_ClipPlayable.SetOverrideLoopTime(true);
            m_ClipPlayable.SetLoopTime(false);
            m_ClipPlayable.SetApplyFootIK(false);

            m_CandidateClipPlayable = AnimationClipPlayable.Create(m_Graph, m_CandidateClip);
            m_CandidateClipPlayable.SetApplyFootIK(false);

            IAnimationWindowPreview[] previewComponents = FetchPostProcessComponents();
            bool requiresDefaultPose = previewComponents != null && previewComponents.Length > 0;
            int  nInputs             = requiresDefaultPose ? 3 : 2;

            // Create a layer mixer if necessary, we'll connect playable nodes to it after having populated AnimationStream.
            AnimationLayerMixerPlayable mixer = AnimationLayerMixerPlayable.Create(m_Graph, nInputs);

            m_GraphRoot = (Playable)mixer;

            // Populate custom playable preview graph.
            if (previewComponents != null)
            {
                foreach (var component in previewComponents)
                {
                    m_GraphRoot = component.BuildPreviewGraph(m_Graph, m_GraphRoot);
                }
            }

            // Finish hooking up mixer.
            int inputIndex = 0;

            if (requiresDefaultPose)
            {
                AnimationMode.RevertPropertyModificationsForGameObject(state.activeRootGameObject);

                EditorCurveBinding[] streamBindings = AnimationUtility.GetAnimationStreamBindings(state.activeRootGameObject);

                m_DefaultPose = new AnimationClip()
                {
                    name = "DefaultPose"
                };

                AnimationWindowUtility.CreateDefaultCurves(state, m_DefaultPose, streamBindings);

                m_DefaultPosePlayable = AnimationClipPlayable.Create(m_Graph, m_DefaultPose);
                m_DefaultPosePlayable.SetApplyFootIK(false);

                mixer.ConnectInput(inputIndex++, m_DefaultPosePlayable, 0, 1.0f);
            }

            mixer.ConnectInput(inputIndex++, m_ClipPlayable, 0, 1.0f);
            mixer.ConnectInput(inputIndex++, m_CandidateClipPlayable, 0, 1.0f);

            if (animator.applyRootMotion)
            {
                var motionX = AnimationMotionXToDeltaPlayable.Create(m_Graph);
                motionX.SetAbsoluteMotion(true);
                motionX.SetInputWeight(0, 1.0f);

                m_Graph.Connect(m_GraphRoot, 0, motionX, 0);

                m_GraphRoot = (Playable)motionX;
            }

            var output = AnimationPlayableOutput.Create(m_Graph, "ouput", animator);

            output.SetSourcePlayable(m_GraphRoot);
            output.SetWeight(0.0f);
        }
示例#8
0
            public EvaluationGraph(RigBuilder rigBuilder, AnimationClip clip, AnimationClip defaultPoseClip, IReadOnlyDictionary <IRigConstraint, IRigConstraint> overrides, IRigConstraint lastConstraint = null)
            {
                m_SyncSceneToStreamLayer = new SyncSceneToStreamLayer();

                bool stopBuilding = false;

                var layers = rigBuilder.layers;

                m_RigLayers = new List <IRigLayer>(layers.Count);
                for (int i = 0; i < layers.Count; ++i)
                {
                    if (stopBuilding == true)
                    {
                        break;
                    }

                    if (layers[i].rig == null || !layers[i].active)
                    {
                        continue;
                    }

                    IRigConstraint[] constraints = RigUtils.GetConstraints(layers[i].rig);
                    if (constraints == null || constraints.Length == 0)
                    {
                        continue;
                    }

                    var newConstraints = new List <IRigConstraint>(constraints.Length);
                    foreach (IRigConstraint constraint in constraints)
                    {
                        if (overrides.TryGetValue(constraint, out IRigConstraint newConstraint))
                        {
                            if (newConstraint != null)
                            {
                                newConstraints.Add(newConstraint);
                            }
                        }
                        else
                        {
                            newConstraints.Add(constraint);
                        }

                        if (constraint == lastConstraint)
                        {
                            stopBuilding = true;
                            break;
                        }
                    }

                    m_RigLayers.Add(new OverrideRigLayer(layers[i].rig, newConstraints.ToArray()));
                }

                m_Graph = PlayableGraph.Create("Evaluation-Graph");
                m_Graph.SetTimeUpdateMode(DirectorUpdateMode.Manual);

                var animator = rigBuilder.GetComponent <Animator>();

                m_Clip = clip;

                var settings = AnimationUtility.GetAnimationClipSettings(m_Clip);

                m_ClipLoopTime = settings.loopTime;

                // Override loop time in clip asset.
                settings.loopTime = false;
                AnimationUtility.SetAnimationClipSettings(m_Clip, settings);

                var defaultPosePlayable = AnimationClipPlayable.Create(m_Graph, defaultPoseClip);
                var clipPlayable        = AnimationClipPlayable.Create(m_Graph, m_Clip);

                defaultPosePlayable.SetApplyFootIK(false);
                clipPlayable.SetApplyFootIK(false);

                AnimationLayerMixerPlayable mixer = AnimationLayerMixerPlayable.Create(m_Graph, 2);

                mixer.ConnectInput(0, defaultPosePlayable, 0, 1.0f);
                mixer.ConnectInput(1, clipPlayable, 0, 1.0f);

                Playable inputPlayable = mixer;

                var playableChains = RigBuilderUtils.BuildPlayables(animator, m_Graph, m_RigLayers, m_SyncSceneToStreamLayer);

                foreach (var chain in playableChains)
                {
                    if (!chain.IsValid())
                    {
                        continue;
                    }

                    chain.playables[0].AddInput(inputPlayable, 0, 1);
                    inputPlayable = chain.playables[chain.playables.Length - 1];
                }

                var output = AnimationPlayableOutput.Create(m_Graph, "bake-output", animator);

                output.SetSourcePlayable(inputPlayable);
            }
示例#9
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());
        }
示例#10
0
 public void SetPlayableInput(int portId, Playable playable, int playablePort)
 {
     m_Mixer.ConnectInput(0, playable, playablePort, 1.0f);
 }