A game about forced loneliness, made by TACStudios
at master 93 lines 3.3 kB view raw
1using System.Collections.Generic; 2using UnityEngine.Animations; 3using UnityEngine.Playables; 4 5namespace UnityEngine.Timeline 6{ 7 // Does a post processing of the weights on an animation track to properly normalize 8 // the mixer weights so that blending does not bring default poses and subtracks, layers and 9 // layer graphs blend correctly 10 class AnimationOutputWeightProcessor : ITimelineEvaluateCallback 11 { 12 struct WeightInfo 13 { 14 public Playable mixer; 15 public Playable parentMixer; 16 public int port; 17 } 18 19 AnimationPlayableOutput m_Output; 20 AnimationMotionXToDeltaPlayable m_MotionXPlayable; 21 readonly List<WeightInfo> m_Mixers = new List<WeightInfo>(); 22 23 public AnimationOutputWeightProcessor(AnimationPlayableOutput output) 24 { 25 m_Output = output; 26 output.SetWeight(0); 27 FindMixers(); 28 } 29 30 void FindMixers() 31 { 32 var playable = m_Output.GetSourcePlayable(); 33 var outputPort = m_Output.GetSourceOutputPort(); 34 35 m_Mixers.Clear(); 36 // only write the final output in playmode. it should always be 1 in editor because we blend to the defaults 37 FindMixers(playable, outputPort, playable.GetInput(outputPort)); 38 } 39 40 // Recursively accumulates mixers. 41 void FindMixers(Playable parent, int port, Playable node) 42 { 43 if (!node.IsValid()) 44 return; 45 46 var type = node.GetPlayableType(); 47 if (type == typeof(AnimationMixerPlayable) || type == typeof(AnimationLayerMixerPlayable)) 48 { 49 // use post fix traversal so children come before parents 50 int subCount = node.GetInputCount(); 51 for (int j = 0; j < subCount; j++) 52 { 53 FindMixers(node, j, node.GetInput(j)); 54 } 55 56 // if we encounter a layer mixer, we assume there is nesting occuring 57 // and we modulate the weight instead of overwriting it. 58 var weightInfo = new WeightInfo 59 { 60 parentMixer = parent, 61 mixer = node, 62 port = port, 63 }; 64 m_Mixers.Add(weightInfo); 65 } 66 else 67 { 68 var count = node.GetInputCount(); 69 for (var i = 0; i < count; i++) 70 { 71 FindMixers(parent, port, node.GetInput(i)); 72 } 73 } 74 } 75 76 public void Evaluate() 77 { 78 float weight = 1; 79 m_Output.SetWeight(1); 80 for (int i = 0; i < m_Mixers.Count; i++) 81 { 82 var mixInfo = m_Mixers[i]; 83 weight = WeightUtility.NormalizeMixer(mixInfo.mixer); 84 mixInfo.parentMixer.SetInputWeight(mixInfo.port, weight); 85 } 86 87 // only write the final weight in player/playmode. In editor, we are blending to the appropriate defaults 88 // the last mixer in the list is the final blend, since the list is composed post-order. 89 if (Application.isPlaying) 90 m_Output.SetWeight(weight); 91 } 92 } 93}