private void CleanClonedStates() { for (int i = m_States.Count - 1; i >= 0; i--) { StateInfo state = m_States[i]; if (state == null) { continue; } if (state.isReadyForCleanup) { AnimationMixerPlayable mixer = GetMixer(state.layer); if (mixer.Equals(AnimationMixerPlayable.Null)) { throw new Exception("Can not get mixer at layer:" + state.layer); } Playable toDestroy = mixer.GetInput(state.indexAtLayer); graph.Disconnect(mixer, state.indexAtLayer); graph.DestroyPlayable(toDestroy); m_States.RemoveState(i); } } }
public override void OnGraphStop(Playable playable) { //if the playable is not valid, then we are destroying, and our children won't be valid either if (!self.IsValid()) { return; } for (int i = 0; i < m_States.Count; i++) { StateInfo state = m_States[i]; if (state == null) { continue; } if (state.fadeSpeed == 0f && state.targetWeight == 0f) { 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 (!input.Equals(Playable.Null)) { input.ResetTime(0f); } } } }
private void ConnectToLayer(StateInfo state, int layer) { AnimationMixerPlayable mixer = AddMixerWhenNotExist(layer); if (mixer.Equals(AnimationMixerPlayable.Null)) { return; } }
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 void DisconnectInput(int index) { StateInfo state = m_States[index]; if (keepStoppedPlayablesConnected) { m_States[index].Pause(); } AnimationMixerPlayable mixer = GetMixer(state.layer); if (mixer.Equals(AnimationMixerPlayable.Null)) { throw new Exception("Can not get mixer at layer:" + state.layer); } graph.Disconnect(mixer, state.indexAtLayer); }
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); }
public void Evaluate() { m_Output.SetWeight(1); for (int i = 0; i < m_Mixers.Count; i++) { var mixInfo = m_Mixers[i]; float weight = mixInfo.modulate ? mixInfo.parentMixer.GetInputWeight(mixInfo.port) : 1.0f; mixInfo.parentMixer.SetInputWeight(mixInfo.port, weight * WeightUtility.NormalizeMixer(mixInfo.mixer)); } float normalizedWeight = WeightUtility.NormalizeMixer(m_LayerMixer); var animator = m_Output.GetTarget(); if (animator == null) { return; } // AnimationMotionXToDeltaPlayable must blend with default values when previewing tracks with absolute root motion. bool blendMotionX = !Application.isPlaying && m_MotionXPlayable.IsValid() && m_MotionXPlayable.IsAbsoluteMotion(); if (blendMotionX) { m_PoseMixer.SetInputWeight(0, normalizedWeight); m_PoseMixer.SetInputWeight(1, 1.0f - normalizedWeight); } else { if (!m_PoseMixer.Equals(AnimationMixerPlayable.Null)) { m_PoseMixer.SetInputWeight(0, 1.0f); m_PoseMixer.SetInputWeight(1, 0.0f); } m_Output.SetWeight(normalizedWeight); } }
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(); }