Maze / Library /PackageCache /com.unity.timeline@1.6.5 /Runtime /Animation /AnimationOutputWeightProcessor.cs
| using System.Collections.Generic; | |
| using UnityEngine.Animations; | |
| using UnityEngine.Playables; | |
| namespace UnityEngine.Timeline | |
| { | |
| // Does a post processing of the weights on an animation track to properly normalize | |
| // the mixer weights so that blending does not bring default poses and subtracks, layers and | |
| // layer graphs blend correctly | |
| class AnimationOutputWeightProcessor : ITimelineEvaluateCallback | |
| { | |
| struct WeightInfo | |
| { | |
| public Playable mixer; | |
| public Playable parentMixer; | |
| public int port; | |
| } | |
| AnimationPlayableOutput m_Output; | |
| AnimationMotionXToDeltaPlayable m_MotionXPlayable; | |
| readonly List<WeightInfo> m_Mixers = new List<WeightInfo>(); | |
| public AnimationOutputWeightProcessor(AnimationPlayableOutput output) | |
| { | |
| m_Output = output; | |
| output.SetWeight(0); | |
| FindMixers(); | |
| } | |
| void FindMixers() | |
| { | |
| var playable = m_Output.GetSourcePlayable(); | |
| var outputPort = m_Output.GetSourceOutputPort(); | |
| m_Mixers.Clear(); | |
| // only write the final output in playmode. it should always be 1 in editor because we blend to the defaults | |
| FindMixers(playable, outputPort, playable.GetInput(outputPort)); | |
| } | |
| // Recursively accumulates mixers. | |
| void FindMixers(Playable parent, int port, Playable node) | |
| { | |
| if (!node.IsValid()) | |
| return; | |
| var type = node.GetPlayableType(); | |
| if (type == typeof(AnimationMixerPlayable) || type == typeof(AnimationLayerMixerPlayable)) | |
| { | |
| // use post fix traversal so children come before parents | |
| int subCount = node.GetInputCount(); | |
| for (int j = 0; j < subCount; j++) | |
| { | |
| FindMixers(node, j, node.GetInput(j)); | |
| } | |
| // if we encounter a layer mixer, we assume there is nesting occuring | |
| // and we modulate the weight instead of overwriting it. | |
| var weightInfo = new WeightInfo | |
| { | |
| parentMixer = parent, | |
| mixer = node, | |
| port = port, | |
| }; | |
| m_Mixers.Add(weightInfo); | |
| } | |
| else | |
| { | |
| var count = node.GetInputCount(); | |
| for (var i = 0; i < count; i++) | |
| { | |
| FindMixers(parent, port, node.GetInput(i)); | |
| } | |
| } | |
| } | |
| public void Evaluate() | |
| { | |
| float weight = 1; | |
| m_Output.SetWeight(1); | |
| for (int i = 0; i < m_Mixers.Count; i++) | |
| { | |
| var mixInfo = m_Mixers[i]; | |
| weight = WeightUtility.NormalizeMixer(mixInfo.mixer); | |
| mixInfo.parentMixer.SetInputWeight(mixInfo.port, weight); | |
| } | |
| // only write the final weight in player/playmode. In editor, we are blending to the appropriate defaults | |
| // the last mixer in the list is the final blend, since the list is composed post-order. | |
| if (Application.isPlaying) | |
| m_Output.SetWeight(weight); | |
| } | |
| } | |
| } | |