protected override Playable OnCreatePlayable(PlayableGraph playableGraph) { AnimationMixerPlayable playable = AnimationMixerPlayable.Create(playableGraph); playable.SetInputCount(InputPorts.Count); InputPorts.ForEach(inputPort => { inputPort.Weight = inputPort.Weight; }); return(playable); }
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 void AddState(string stateName, bool isBlendTree, Playable playable, AnimationClip clip = null, string groupName = null, BlendTreeConfig[] blendTreePlayables = null, string blendTreeParam = null) { if (FindState(stateName) != null) { Debug.LogErrorFormat("Add state fail, state:{0} has existed!", stateName); return; } if (isBlendTree && (blendTreePlayables == null || blendTreeParam == null)) { Debug.LogError("BlendTreePlayables or blendTreeParam is null but isBlendTree is true!"); return; } StateInfo state = new StateInfo(); state.stateName = stateName; state.isBlendTree = isBlendTree; state.stateGroupName = groupName; state.SetPlayable(playable); if (isBlendTree) { state.SetBlendTreePlayable(blendTreePlayables); state.blendTreeParameter = blendTreeParam; } else { state.Clip = clip; } state.Pause(); int emptyIndex = m_States.FindIndex(s => s == null); if (emptyIndex != -1) { m_States[emptyIndex] = state; state.index = emptyIndex; } else { state.index = m_States.Count; m_States.Add(state); m_Mixer.SetInputCount(m_States.Count); // 增加输入端口 } m_Count++; }
//=========================================================================================== /** * @brief * *********************************************************************************************/ private void SetupPreviewGraph() { List <AnimationClip> clips = m_data.Clips; m_blendWeights = new List <float>(clips.Count + 1); AnimationMixerPlayable mixer = MxMPreviewScene.Mixer; mixer.SetInputCount(clips.Count); float blendSpaceLength = clips[0].length; float normalizedClipSpeed = 1f; for (int i = 0; i < clips.Count; ++i) { AnimationClip clip = clips[i]; var clipPlayable = AnimationClipPlayable.Create(MxMPreviewScene.PlayableGraph, clip); if (clipPlayable.IsValid()) { if (m_spNormalizeTime.boolValue) { normalizedClipSpeed = clip.length / blendSpaceLength; } clipPlayable.SetTime(0.0); clipPlayable.SetSpeed(normalizedClipSpeed); mixer.ConnectInput(i, clipPlayable, 0); if (i > 0) { mixer.SetInputWeight(i, 0f); m_blendWeights.Add(0f); } else { mixer.SetInputWeight(i, 1f); m_blendWeights.Add(1f); } } } CalculateBlendWeights(); ApplyBlendWeights(); m_lastPlayIncTime = (float)EditorApplication.timeSinceStartup; }
// 取得可用的或新的输入索引 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(); } } }
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); }
public bool Add(AnimationClip clip, string stateName, PlayableGraph graph, AnimationMixerPlayable mixer) { var findState = Find(stateName); if (findState == null) { var addState = new EasyAnimationState(clip, stateName, graph); states.Add(addState); addState.Stop(); addState.index = states.Count - 1; int inputCount = addState.index + 1; mixer.SetInputCount(inputCount); graph.Connect(addState.Playable, 0, mixer, addState.index); DebugLog.Normal($"EasyAnimationStateManager.Add : アニメーションステートを追加しました。{clip.name}", DebugLogColor.animation); return(true); } DebugLog.Warning($"EasyAnimationStateManager.Add : 同名アニメーションステートが存在しているため、追加に失敗しました。{clip.name}", DebugLogColor.animation); return(false); }
private StateInfo DoAddClip(string name, AnimationClip clip) { //Start new State StateInfo newState = m_States.InsertState(); //LoopしないものはWrapModeにOnceを明示的に指定 if (!clip.isLooping && clip.wrapMode == WrapMode.Default) { clip.wrapMode = WrapMode.Once; } newState.Initialize(name, clip, clip.wrapMode); //Find at which input the state will be connected int index = newState.index; //Increase input count if needed if (index == m_Mixer.GetInputCount()) { m_Mixer.SetInputCount(index + 1); } 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 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 SetInputCount(int count) { _mixer.SetInputCount(count); }
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(); }