using System; using System.Collections.Generic; using System.Linq; using UnityEngine.Animations; using UnityEngine.Audio; using UnityEngine.Playables; namespace UnityEngine.Timeline { // Token: 0x0200001D RID: 29 public class TimelinePlayable : PlayableBehaviour { // Token: 0x060000ED RID: 237 RVA: 0x00006490 File Offset: 0x00004690 public static ScriptPlayable Create(PlayableGraph graph, IList tracks, GameObject go, bool autoRebalance, bool createOutputs) { if (tracks == null) { throw new ArgumentNullException("Tracks list is null", "tracks"); } if (go == null) { throw new ArgumentNullException("GameObject parameter is null", "go"); } ScriptPlayable scriptPlayable = ScriptPlayable.Create(graph, 0); TimelinePlayable behaviour = scriptPlayable.GetBehaviour(); behaviour.Compile(graph, scriptPlayable, tracks, go, autoRebalance, createOutputs); return scriptPlayable; } // Token: 0x060000EE RID: 238 RVA: 0x000064FC File Offset: 0x000046FC public void Compile(PlayableGraph graph, Playable timelinePlayable, IList tracks, GameObject go, bool autoRebalance, bool createOutputs) { if (tracks == null) { throw new ArgumentNullException("Tracks list is null", "tracks"); } if (go == null) { throw new ArgumentNullException("GameObject parameter is null", "go"); } int num = tracks.Count * 2 + tracks.Count; this.m_CurrentListOfActiveClips = this.m_IntervalTree.AllocateCache(num); this.m_ActiveClips = this.m_IntervalTree.AllocateCache(num); IList list = tracks.Where((TrackAsset t) => t.soloed).ToList(); if (list.Count == 0) { list = tracks; } this.m_EvaluateCallbacks.Clear(); this.m_PlayableCache.Clear(); this.CompileTrackList(graph, timelinePlayable, list, go, createOutputs); } // Token: 0x060000EF RID: 239 RVA: 0x000065CC File Offset: 0x000047CC private void CompileTrackList(PlayableGraph graph, Playable timelinePlayable, IEnumerable tracks, GameObject go, bool createOutputs) { foreach (TrackAsset trackAsset in tracks) { if (trackAsset.compilable) { if (!this.m_IntervalTree.Contains(trackAsset)) { trackAsset.SortClips(); this.m_IntervalTree.Add(trackAsset); this.CreateTrackPlayable(graph, timelinePlayable, trackAsset, go, createOutputs); } } } } // Token: 0x060000F0 RID: 240 RVA: 0x00006660 File Offset: 0x00004860 private void CreateTrackOutput(PlayableGraph graph, GameObject go, TrackAsset track, Playable playable, int port) { if (!track.isSubTrack) { IEnumerable outputs = track.outputs; foreach (PlayableBinding playableBinding in outputs) { if (playableBinding.streamType == DataStreamType.Animation) { AnimationPlayableOutput animationPlayableOutput = AnimationPlayableOutput.Create(graph, playableBinding.streamName, null); animationPlayableOutput.SetReferenceObject(playableBinding.sourceObject); animationPlayableOutput.SetSourcePlayable(playable); animationPlayableOutput.SetSourceInputPort(port); this.m_EvaluateCallbacks.Add(new AnimationOutputWeightProcessor(animationPlayableOutput)); } else if (playableBinding.streamType == DataStreamType.Audio) { AudioPlayableOutput audioPlayableOutput = AudioPlayableOutput.Create(graph, playableBinding.streamName, null); audioPlayableOutput.SetReferenceObject(playableBinding.sourceObject); audioPlayableOutput.SetSourcePlayable(playable); audioPlayableOutput.SetSourceInputPort(port); } else { if (playableBinding.streamType != DataStreamType.None) { throw new NotImplementedException("Unsupported stream type"); } ScriptPlayableOutput scriptPlayableOutput = ScriptPlayableOutput.Create(graph, playableBinding.streamName); scriptPlayableOutput.SetReferenceObject(playableBinding.sourceObject); scriptPlayableOutput.SetSourcePlayable(playable); scriptPlayableOutput.SetSourceInputPort(port); } } } } // Token: 0x060000F1 RID: 241 RVA: 0x000067B8 File Offset: 0x000049B8 private static Playable CreatePlayableGraph(PlayableGraph graph, TrackAsset asset, GameObject go, IntervalTree tree) { return asset.CreatePlayableGraph(graph, go, tree); } // Token: 0x060000F2 RID: 242 RVA: 0x000067D8 File Offset: 0x000049D8 private Playable CreateTrackPlayable(PlayableGraph graph, Playable timelinePlayable, TrackAsset track, GameObject go, bool createOutputs) { Playable playable; TimelinePlayable.ConnectionCache connectionCache; if (!track.compilable) { playable = timelinePlayable; } else if (this.m_PlayableCache.TryGetValue(track, out connectionCache)) { playable = connectionCache.playable; } else if (track.name == "root") { playable = timelinePlayable; } else { TrackAsset trackAsset = track.parent as TrackAsset; Playable playable2 = ((!(trackAsset != null)) ? timelinePlayable : this.CreateTrackPlayable(graph, timelinePlayable, trackAsset, go, createOutputs)); Playable playable3 = TimelinePlayable.CreatePlayableGraph(graph, track, go, this.m_IntervalTree); bool flag = false; if (!playable3.IsValid()) { throw new InvalidOperationException(string.Concat(new object[] { track.name, "(", track.GetType(), ") did not produce a valid playable. Use the compilable property to indicate whether the track is valid for processing" })); } if (playable2.IsValid() && playable3.IsValid()) { int inputCount = playable2.GetInputCount(); playable2.SetInputCount(inputCount + 1); flag = graph.Connect(playable3, 0, playable2, inputCount); playable2.SetInputWeight(inputCount, 1f); } if (createOutputs && flag) { this.CreateTrackOutput(graph, go, track, playable2, playable2.GetInputCount() - 1); } this.CacheTrack(track, playable3, (!flag) ? (-1) : (playable2.GetInputCount() - 1), playable2); playable = playable3; } return playable; } // Token: 0x060000F3 RID: 243 RVA: 0x00006946 File Offset: 0x00004B46 public override void PrepareFrame(Playable playable, FrameData info) { this.Evaluate(playable, info); } // Token: 0x060000F4 RID: 244 RVA: 0x00006954 File Offset: 0x00004B54 private void Evaluate(Playable playable, FrameData frameData) { if (this.m_IntervalTree != null) { double time = playable.GetTime(); this.m_ActiveBit = ((this.m_ActiveBit != 0) ? 0 : 1); this.m_CurrentListOfActiveClips.Clear(); this.m_IntervalTree.IntersectsWith(DiscreteTime.GetNearestTick(time), this.m_ActiveBit, ref this.m_CurrentListOfActiveClips); for (int i = 0; i < this.m_ActiveClips.Count; i++) { RuntimeClipBase runtimeClipBase = this.m_ActiveClips[i]; if (runtimeClipBase.intervalBit != this.m_ActiveBit) { runtimeClipBase.enable = false; } } for (int j = 0; j < this.m_CurrentListOfActiveClips.Count; j++) { this.m_CurrentListOfActiveClips[j].EvaluateAt(time, frameData); } this.m_ActiveClips.Clear(); this.m_ActiveClips.AddRange(this.m_CurrentListOfActiveClips); int count = this.m_EvaluateCallbacks.Count; for (int k = 0; k < count; k++) { this.m_EvaluateCallbacks[k].Evaluate(); } } } // Token: 0x060000F5 RID: 245 RVA: 0x00006A84 File Offset: 0x00004C84 private void CacheTrack(TrackAsset track, Playable playable, int port, Playable parent) { this.m_PlayableCache[track] = new TimelinePlayable.ConnectionCache { playable = playable, port = port, parent = parent, evalWeight = 0f }; } // Token: 0x0400006D RID: 109 private IntervalTree m_IntervalTree = new IntervalTree(); // Token: 0x0400006E RID: 110 private List m_ActiveClips = new List(); // Token: 0x0400006F RID: 111 private List m_CurrentListOfActiveClips; // Token: 0x04000070 RID: 112 private int m_ActiveBit = 0; // Token: 0x04000071 RID: 113 private List m_EvaluateCallbacks = new List(); // Token: 0x04000072 RID: 114 private Dictionary m_PlayableCache = new Dictionary(); // Token: 0x0200001E RID: 30 private struct ConnectionCache { // Token: 0x04000074 RID: 116 public Playable playable; // Token: 0x04000075 RID: 117 public int port; // Token: 0x04000076 RID: 118 public Playable parent; // Token: 0x04000077 RID: 119 public float evalWeight; } } }