Пример #1
0
    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);
            }
        }
    }
Пример #2
0
    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);
                }
            }
        }
    }
Пример #3
0
    private void ConnectToLayer(StateInfo state, int layer)
    {
        AnimationMixerPlayable mixer = AddMixerWhenNotExist(layer);

        if (mixer.Equals(AnimationMixerPlayable.Null))
        {
            return;
        }
    }
Пример #4
0
    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));
    }
Пример #5
0
    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);
    }
Пример #6
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);
    }
Пример #7
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);
    }
        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);
            }
        }
Пример #9
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();
    }