コード例 #1
0
        protected override Playable OnCreatePlayable(PlayableGraph playableGraph)
        {
            AnimationMixerPlayable playable = AnimationMixerPlayable.Create(playableGraph);

            playable.SetInputCount(InputPorts.Count);

            InputPorts.ForEach(inputPort =>
            {
                inputPort.Weight = inputPort.Weight;
            });

            return(playable);
        }
コード例 #2
0
        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);
                }
            }
        }
コード例 #3
0
            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++;
            }
コード例 #4
0
        //===========================================================================================

        /**
         *  @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;
        }
コード例 #5
0
        // 取得可用的或新的输入索引
        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
        }
コード例 #6
0
ファイル: AnimMixer.cs プロジェクト: mrcece/MotionFramework
        /// <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();
                }
            }
        }
コード例 #7
0
    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);
    }
コード例 #8
0
        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);
        }
コード例 #9
0
    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);
    }
コード例 #10
0
    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);
    }
コード例 #11
0
 public void SetInputCount(int count)
 {
     _mixer.SetInputCount(count);
 }
コード例 #12
0
    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();
    }