//=========================================================================================== /** * @brief * *********************************************************************************************/ private void AddClipToPreview(AnimationClip a_clip) { if (m_previewActive && a_clip != null) { m_blendWeights.Add(0f); AnimationMixerPlayable mixer = MxMPreviewScene.Mixer; int inputId = mixer.GetInputCount(); mixer.SetInputCount(inputId + 1); var clipPlayable = AnimationClipPlayable.Create(MxMPreviewScene.PlayableGraph, a_clip); mixer.ConnectInput(inputId, clipPlayable, 0); for (int i = 0; i < mixer.GetInputCount(); ++i) { var playable = mixer.GetInput(i); if (playable.IsValid()) { playable.SetTime(0f); } } CalculateBlendWeights(); ApplyBlendWeights(); } }
public void ClearMainMixerInput() { for (int i = 0; i < mixer.GetInputCount(); i++) { mixer.GetInput(i).Destroy(); } mixer.SetInputCount(0); asBuffor = null; }
public Playable GetInput(int index) { if (index >= m_Mixer.GetInputCount()) { return(Playable.Null); } return(m_Mixer.GetInput(index)); }
public override void PrepareFrame(Playable owner, FrameData info) { int ClipCount = m_mixerPlayable.GetInputCount(); if (ClipCount == 0) { return; } m_timeToNextClip -= info.deltaTime; if (m_timeToNextClip <= 0.0f) { m_currentClipIndex++; if (m_currentClipIndex >= ClipCount) { m_currentClipIndex = 0; } var currentClip = (AnimationClipPlayable)m_mixerPlayable.GetInput(m_currentClipIndex); //SetTime(0),从头开始播放动画 currentClip.SetTime(0); m_timeToNextClip = currentClip.GetAnimationClip().length; } //利用权重来设置当前播放的Clip for (int clipIndex = 0; clipIndex < ClipCount; ++clipIndex) { m_mixerPlayable.SetInputWeight(clipIndex, clipIndex == m_currentClipIndex ? 1 : 0); } }
public void PlayAnimation(Playable owner, AnimationClip clip) { var bindIndex = _clipData.FindIndex(cd => cd.Clip == clip); if (bindIndex == -1) { owner.Pause(); return; } var data = _clipData[bindIndex]; CurrentClipIndex = data.MixerIndex; var clipPlayable = (AnimationClipPlayable)Mixer.GetInput(CurrentClipIndex); clipPlayable.SetTime(0.0); var inputCount = Mixer.GetInputCount(); for (var idx = 0; idx < inputCount; idx++) { Mixer.SetInputWeight(idx, idx != CurrentClipIndex ? 0.0f : 1.0f); } owner.Play(); }
public static void RemoveZeroWeightsInputs(AnimationMixerPlayable mixer) { int size = mixer.GetInputCount(); for (int i = 0; i < size; i++) { if (mixer.GetInputWeight(i) <= 0) { mixer.GetInput(i).Destroy(); for (int j = i + 1; j < size; j++) { // double localTime = ((AnimationClipPlayable)mixer.GetInput(j)).GetTime(); float _weight = mixer.GetInputWeight(j); Playable clip = mixer.GetInput(j); // clip.SetTime(localTime); mixer.DisconnectInput(j); mixer.ConnectInput(j - 1, clip, 0); mixer.SetInputWeight(j - 1, _weight); } i--; size--; mixer.SetInputCount(size); } } }
public void BlendPlayablesInStateMixer( ref AnimationMixerPlayable stateMixer, List <float> blendingSpeeds, List <float> currentWeights, float minWeightToAchive = 0f, float blendTime = 0.5f ) { int size = stateMixer.GetInputCount(); float weightSum = 0; for (int i = 0; i < size; i++) { if (i < (size - 1) && minWeightToAchive <= currentWeights[i] && blendingSpeeds[i] > 0) { blendingSpeeds[i] = -(currentWeights[i] / blendTime); } currentWeights[i] = Mathf.Clamp01(currentWeights[i] + (blendingSpeeds[i] * Time.deltaTime)); weightSum += currentWeights[i]; } for (int i = 0; i < size; i++) { stateMixer.SetInputWeight(i, currentWeights[i] / weightSum); } }
//=========================================================================================== /** * @brief * *********************************************************************************************/ public void EndPreviewLocal() { if (!m_previewActive) { return; } AnimationMixerPlayable mixer = MxMPreviewScene.Mixer; if (mixer.IsValid()) { for (int i = 0; i < mixer.GetInputCount(); ++i) { var clipPlayable = mixer.GetInput(0); if (clipPlayable.IsValid()) { mixer.DisconnectInput(0); clipPlayable.Destroy(); } } } m_previewActive = false; m_previewBlendSpace = null; }
public override void PrepareFrame(Playable playable, FrameData info) { if (mixer.GetInputCount() == 0) { return; } timeToNextClip -= info.deltaTime; if (timeToNextClip <= 0) { MoveToNextClip(); } UpdateWeights(); }
public void AddClipPlayable( AnimationMixerPlayable mixer, AnimationClip animation, bool passIK, bool passFootIK = false, double localTime = 0d, float weight = 0f ) { AnimationClipPlayable playable = AnimationClipPlayable.Create(this.graph, animation); playable.SetApplyPlayableIK(passIK); playable.SetApplyFootIK(passFootIK); mixer.AddInput(playable, 0, weight); mixer.GetInput(mixer.GetInputCount() - 1).SetTime(localTime); mixer.GetInput(mixer.GetInputCount() - 1).SetTime(localTime); }
// Use this for initialization void Start() { animator = GetComponent <Animator>(); playableGraph = PlayableGraph.Create("ClairePlayableGraph"); playableGraph.SetTimeUpdateMode(DirectorUpdateMode.GameTime); var playableOutput = AnimationPlayableOutput.Create(playableGraph, "Animation", animator); // Create Top Level Layer Mixer AnimationLayerMixerPlayable mixerLayerPlayable = AnimationLayerMixerPlayable.Create(playableGraph, 2); playableOutput.SetSourcePlayable(mixerLayerPlayable); // Create an Emotion Mixer mixerEmotionPlayable = AnimationMixerPlayable.Create(playableGraph, 4); // Wrap AnimController runtimeAnimController = animator.runtimeAnimatorController; var runtimeAnimControllerPlayable = AnimatorControllerPlayable.Create(playableGraph, runtimeAnimController); // Connect to Top Level Layer Mixer playableGraph.Connect(runtimeAnimControllerPlayable, 0, mixerLayerPlayable, 0); playableGraph.Connect(mixerEmotionPlayable, 0, mixerLayerPlayable, 1); mixerLayerPlayable.SetInputWeight(0, 1.0f); mixerLayerPlayable.SetInputWeight(1, 1.0f); mixerLayerPlayable.SetLayerMaskFromAvatarMask(1, headMask); // Wrap the clips in a playable pHappy = AnimationClipPlayable.Create(playableGraph, happy); pHappyTransitionIn = AnimationClipPlayable.Create(playableGraph, happyTransitionIn); pAngry = AnimationClipPlayable.Create(playableGraph, angry); pAngryTransitionIn = AnimationClipPlayable.Create(playableGraph, angryTransitionIn); pTPose = AnimationClipPlayable.Create(playableGraph, tPose); // Setup Durations for IsDone Checks pHappyTransitionIn.SetDuration(happyTransitionIn.length); pAngryTransitionIn.SetDuration(angryTransitionIn.length); // Connect to Emotion Mixer mixerEmotionPlayable.SetInputCount(5); // InputCount needs to be == to the number of connected clips (for normalization purposes) playableGraph.Connect(pHappy, 0, mixerEmotionPlayable, 0); playableGraph.Connect(pHappyTransitionIn, 0, mixerEmotionPlayable, 1); playableGraph.Connect(pAngry, 0, mixerEmotionPlayable, 2); playableGraph.Connect(pAngryTransitionIn, 0, mixerEmotionPlayable, 3); playableGraph.Connect(pTPose, 0, mixerEmotionPlayable, 4); Debug.Log("INputLength: " + mixerEmotionPlayable.GetInputCount()); // Activate T Pose mixerEmotionPlayable.SetInputWeight(4, 1.0f); Debug.Log("Happy Transition Time: " + pHappyTransitionIn.GetDuration()); // Plays the Graph playableGraph.Play(); }
void normalizeWeights() { int length = mixerEmotionPlayable.GetInputCount(); float sumOfWeights = 0; for (int i = 0; i < length; i++) { if (mixerEmotionPlayable.GetInputWeight(i) > 0f) { sumOfWeights += mixerEmotionPlayable.GetInputWeight(i); } } for (int i = 0; i < length; i++) { if (mixerEmotionPlayable.GetInputWeight(i) > 0f) { mixerEmotionPlayable.SetInputWeight(i, mixerEmotionPlayable.GetInputWeight(i) / sumOfWeights); } } normalize = false; }
public void Initialize(AnimationClip[] clipArray, Playable owner, PlayableGraph graph) { owner.SetInputCount(1); m_mixerPlayable = AnimationMixerPlayable.Create(graph, clipArray.Length); graph.Connect(m_mixerPlayable, 0, owner, 0); owner.SetInputWeight(0, 1); //根据clipArray创建AnimationClipPlayable并连接 for (int clipIndex = 0; clipIndex < m_mixerPlayable.GetInputCount(); ++clipIndex) { graph.Connect(AnimationClipPlayable.Create(graph, clipArray[clipIndex]), 0, m_mixerPlayable, clipIndex); } }
public void RemoveZeroWeightsInputsAnimations( AnimationMixerPlayable mixer, List <float> blendingWeights, List <float> currentWeights, List <int> curretClipsIndex, List <LogicAnimationsSequence> animationsSequences ) { int size = mixer.GetInputCount(); for (int i = 0; i < size; i++) { if (currentWeights[i] <= 0f) { int sequenceMixerInputsCount = mixer.GetInput(i).GetInputCount(); if (sequenceMixerInputsCount > 0) { for (int mixerInputInputsIndex = 0; mixerInputInputsIndex < sequenceMixerInputsCount; mixerInputInputsIndex++) { mixer.GetInput(i).GetInput(mixerInputInputsIndex).Destroy(); } for (int as_Index = 0; as_Index < animationsSequences.Count; as_Index++) { if (curretClipsIndex[i] == animationsSequences[as_Index].dataIndex) { animationsSequences.RemoveAt(as_Index); break; } } } mixer.GetInput(i).Destroy(); blendingWeights.RemoveAt(i); curretClipsIndex.RemoveAt(i); currentWeights.RemoveAt(i); for (int j = i + 1; j < size; j++) { // double localTime = ((AnimationClipPlayable)mixer.GetInput(j)).GetTime(); float _weight = mixer.GetInputWeight(j); Playable clip = mixer.GetInput(j); // clip.SetTime(localTime); mixer.DisconnectInput(j); mixer.ConnectInput(j - 1, clip, 0); mixer.SetInputWeight(j - 1, _weight); } i--; size--; mixer.SetInputCount(size); } } }
public Playable GetInput(int layer, int index) { AnimationMixerPlayable mixer = GetMixer(layer); if (mixer.Equals(AnimationMixerPlayable.Null)) { return(Playable.Null); } if (index >= mixer.GetInputCount()) { return(Playable.Null); } return(mixer.GetInput(index)); }
// 取得可用的或新的输入索引 private int GetInputIndex(AnimationMixerPlayable mixerPlayable) { var count = mixerPlayable.GetInputCount(); for (int i = 0; i < count; i++) { var p = mixerPlayable.GetInput(i); if (p.IsNull()) { mixerPlayable.SetInputWeight(i, 0); return(i); } } mixerPlayable.SetInputCount(count + 1); return(count); //index }
/// <summary> /// 播放指定动画 /// </summary> public void Play(AnimState animState, float fadeDuration) { // 重新激活混合器 _isQuiting = false; StartWeightFade(1f, 0); if (IsContains(animState) == false) { // 优先插入到一个空位 int index = _states.FindIndex(s => s == null); if (index == -1) { // Increase input count int inputCount = _mixer.GetInputCount(); _mixer.SetInputCount(inputCount + 1); animState.Connect(_mixer, inputCount); _states.Add(animState); } else { animState.Connect(_mixer, index); _states[index] = animState; } } for (int i = 0; i < _states.Count; i++) { var state = _states[i]; if (state == null) { continue; } if (state == animState) { state.StartWeightFade(1f, fadeDuration); state.PlayNode(); } else { state.StartWeightFade(0f, fadeDuration); state.PauseNode(); } } }
public void PlayClip(string clipName) { if (!clipIndexes.ContainsKey(clipName)) { return; } int playingClipIndex = clipIndexes[clipName]; for (int i = 0; i < animationMixer.GetInputCount(); i++) { if (i != playingClipIndex) { animationMixer.SetInputWeight(i, 0); } else { animationMixer.SetInputWeight(i, 1); } } }
private void ConnectInput(int index) { StateInfo state = m_States[index]; AnimationMixerPlayable mixer = GetMixer(state.layer); if (mixer.Equals(AnimationMixerPlayable.Null)) { throw new Exception("Can not get mixer at layer:" + state.layer); } int stateCountByLayer = m_States.GetCountByLayer(state.layer); if (stateCountByLayer > mixer.GetInputCount()) { mixer.SetInputCount(stateCountByLayer); } mixer.DisconnectInput(state.indexAtLayer); graph.Connect(state.playable, 0, mixer, state.indexAtLayer); }
private StateInfo DoAddClip(string name, AnimationClip clip) { //Start new State StateInfo newState = m_States.InsertState(); newState.Initialize(name, clip, clip.wrapMode); //Find at which input the state will be connected int index = newState.index; //Increase input count if needed AnimationMixerPlayable mixer = AddMixerWhenNotExist(newState.layer); if (!mixer.Equals(AnimationMixerPlayable.Null)) { int stateCountByLayer = m_States.GetCountByLayer(newState.layer); if (stateCountByLayer == mixer.GetInputCount()) { mixer.SetInputCount(stateCountByLayer); } } var clipPlayable = AnimationClipPlayable.Create(graph, clip); clipPlayable.SetApplyFootIK(false); clipPlayable.SetApplyPlayableIK(false); if (!clip.isLooping || newState.wrapMode == WrapMode.Once) { clipPlayable.SetDuration(clip.length); } newState.SetPlayable(clipPlayable); newState.Pause(); if (keepStoppedPlayablesConnected) { ConnectInput(newState.index); } return(newState); }
private bool AnimationClipIsPlaying(AnimationMixerPlayable mixerPlayable, AnimationClip clip, out AnimationClipPlayable playable) { var count = mixerPlayable.GetInputCount(); for (int i = 0; i < count; i++) { var p = mixerPlayable.GetInput(i); if (p.IsNull() == false) { if (p.IsPlayableOfType <AnimationClipPlayable>()) { playable = (AnimationClipPlayable)p; if (((AnimationClipPlayable)p).GetAnimationClip() == clip) { return(true); } } } } playable = (AnimationClipPlayable)Playable.Null; return(false); }
/// <summary> /// Update is called once per frame /// </summary> private void Update() { if (animationMixer.GetInputCount() == 0 || currentAnimationList.Count == 0) { // No valid clip input. return; } AnimationComponent firstAnimation = currentAnimationList[0]; AnimationComponent secondAnimation = null; if (currentAnimationList.Count >= 2) { secondAnimation = currentAnimationList[1]; } if (firstAnimation != null) { switch (firstAnimation.CurrentStatus) { case AnimationComponent.Status.Pending: firstAnimation.Start(); break; case AnimationComponent.Status.Processing: firstAnimation.Tick(); break; case AnimationComponent.Status.Done: if (currentAnimationList.Count == 1) { firstAnimation .SetStartBlendingTime(-1.0f) .SetEndBlendingTime(99999.0f) .Reset(); } else if (currentAnimationList.Count >= 2) { currentAnimationList.Remove(firstAnimation); } break; } // We can start blend next clip. if (firstAnimation.CanStartNextClip) { switch (secondAnimation.CurrentStatus) { case AnimationComponent.Status.Pending: secondAnimation.Start(); break; case AnimationComponent.Status.Processing: secondAnimation.Tick(); break; case AnimationComponent.Status.Done: // Impossibile break; } } } }
public void CreateBlendMotionMatchingAnimation( MotionMatchingData data, int dataIndex, AnimationMixerPlayable stateMixer, double localTime, float blendTime, List <float> blendingSpeeds, List <float> currentWeights, List <LogicAnimationsSequence> animationsSequences, bool passIK, bool passFootIK, float newInputStartWeight = 0f, float minWeightToAchive = 0f, float speedMulti = 1f ) { if (stateMixer.GetInputCount() > 0) { if (currentWeights[currentWeights.Count - 1] >= minWeightToAchive) { blendingSpeeds[blendingSpeeds.Count - 1] = -(stateMixer.GetInputWeight(stateMixer.GetInputCount() - 1) / blendTime); } } currentWeights.Add(newInputStartWeight); blendingSpeeds.Add(1f / blendTime); switch (data.dataType) { case AnimationDataType.SingleAnimation: AnimationClipPlayable playable_SA = AnimationClipPlayable.Create(graph, data.clips[0]); playable_SA.SetApplyPlayableIK(passIK); playable_SA.SetApplyFootIK(passFootIK); playable_SA.SetTime(localTime - Time.deltaTime); playable_SA.SetTime(localTime); playable_SA.SetSpeed(speedMulti); stateMixer.AddInput(playable_SA, 0, newInputStartWeight); break; case AnimationDataType.BlendTree: AnimationMixerPlayable mixerPlayable = AnimationMixerPlayable.Create(this.graph); stateMixer.AddInput(mixerPlayable, 0, newInputStartWeight); for (int i = 0; i < data.clips.Count; i++) { AnimationClipPlayable playable_BT = AnimationClipPlayable.Create(this.graph, data.clips[i]); playable_BT.SetApplyPlayableIK(passIK); playable_BT.SetApplyFootIK(passFootIK); playable_BT.SetTime(localTime - Time.deltaTime); playable_BT.SetTime(localTime); playable_BT.SetSpeed(speedMulti); mixerPlayable.AddInput(playable_BT, 0, data.blendTreeWeights[i]); } break; case AnimationDataType.AnimationSequence: animationsSequences.Add(new LogicAnimationsSequence(data, dataIndex)); int new_ASIndex = animationsSequences.Count - 1; animationsSequences[new_ASIndex].mixer = AnimationMixerPlayable.Create(this.graph); stateMixer.AddInput(animationsSequences[new_ASIndex].mixer, 0, newInputStartWeight); animationsSequences[new_ASIndex].CreateAnimationsInTime((float)localTime, this, passIK, passFootIK); break; } }
private void UpdateStates(float deltaTime) { mustUpdateWeights.Clear(); totalWeights.Clear(); for (int i = 0; i < m_States.Count; i++) { StateInfo state = m_States[i]; //Skip deleted states if (state == null) { continue; } //Update crossfade weight if (state.fading) { state.SetWeight(Mathf.MoveTowards(state.weight, state.targetWeight, state.fadeSpeed * deltaTime)); if (Mathf.Approximately(state.weight, state.targetWeight)) { state.ForceWeight(state.targetWeight); if (state.weight == 0f) { state.Stop(); } } } if (state.layerDirty >= 0) { AnimationMixerPlayable lastMixer = GetMixer(state.layerDirty); if (!lastMixer.Equals(AnimationMixerPlayable.Null)) { if (lastMixer.GetInput(state.indexAtLayer).Equals(state.playable)) { graph.Disconnect(lastMixer, state.indexAtLayer); } } AnimationMixerPlayable mixer = AddMixerWhenNotExist(state.layer); if (mixer.Equals(AnimationMixerPlayable.Null)) { throw new Exception("Can not get mixer at layer:" + state.layer); } state.indexAtLayer = m_States.GetAvailableIndexAtLayer(state.layer, state); int stateCountByLayer = m_States.GetCountByLayer(state.layer); if (stateCountByLayer > mixer.GetInputCount()) { mixer.SetInputCount(stateCountByLayer); } graph.Connect(state.playable, 0, mixer, state.indexAtLayer); } if (state.enabledDirty) { if (state.enabled) { state.Play(); } else { state.Pause(); } if (!keepStoppedPlayablesConnected) { AnimationMixerPlayable mixer = GetMixer(state.layer); if (mixer.Equals(AnimationMixerPlayable.Null)) { throw new Exception("Can not get mixer at layer:" + state.layer); } Playable input = mixer.GetInput(state.indexAtLayer); //if state is disabled but the corresponding input is connected, disconnect it if (input.IsValid() && !state.enabled) { DisconnectInput(i); } else if (state.enabled && !input.IsValid()) { ConnectInput(state.index); } } } if (state.enabled && state.wrapMode == WrapMode.Once) { bool stateIsDone = state.isDone; float speed = state.speed; float time = state.GetTime(); float duration = state.playableDuration; stateIsDone |= speed < 0f && time < 0f; stateIsDone |= speed >= 0f && time >= duration; if (stateIsDone) { state.Stop(); state.Disable(); if (!keepStoppedPlayablesConnected) { DisconnectInput(state.index); } } } if (!totalWeights.ContainsKey(state.layer)) { totalWeights.Add(state.layer, 0.0f); } if (!mustUpdateWeights.ContainsKey(state.layer)) { mustUpdateWeights.Add(state.layer, false); } totalWeights[state.layer] += state.weight; if (state.weightDirty) { mustUpdateWeights[state.layer] = true; } state.ResetDirtyFlags(); } var e = mustUpdateWeights.GetEnumerator(); while (e.MoveNext()) { if (e.Current.Value) { float totalWeight = totalWeights[e.Current.Key]; bool hasAnyWeight = totalWeight > 0.0f; for (int i = 0; i < m_States.Count; i++) { StateInfo state = m_States[i]; if (state == null || state.layer != e.Current.Key) { continue; } AnimationMixerPlayable mixer = GetMixer(state.layer); if (mixer.Equals(AnimationMixerPlayable.Null)) { throw new Exception("Can not get mixer at layer:" + state.layer); } float weight = hasAnyWeight ? state.weight / totalWeight : 0.0f; mixer.SetInputWeight(state.indexAtLayer, weight); } } } mustUpdateWeights.Clear(); totalWeights.Clear(); }