//============================================================================================ /** * @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; }
//============================================================================================ /** * @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; }
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); }
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); }
//============================================================================================================ //モーションを再生する 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); }
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); }
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); }
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()); }
public void SetPlayableInput(int portId, Playable playable, int playablePort) { m_Mixer.ConnectInput(0, playable, playablePort, 1.0f); }