private IEnumerator AnimationRoutine(FrameData frameData, ITransition frameTransition, int indexOfTransition) { var oldElements = GetActiveElementsNotPresentInNewFrame(frameData).ToList(); _animations.Clear(); foreach (var element in oldElements) { var oldElementTransition = frameTransition; if (element.Data.OverrideTransition != null) { oldElementTransition = element.Data.OverrideTransition[0]; } _animations.Add(oldElementTransition.TransitionOldSceneObjectOut(element.SceneObject)); } foreach (var element in frameData.Elements) { var alreadyPresentElement = _activeElements.FirstOrDefault(el => el.Data == element); if (alreadyPresentElement != null) { alreadyPresentElement.SceneObject.transform.SetAsLastSibling(); } else { var sceneObject = Instantiate(element.Prefab, Root); var instance = new FrameElementInstance { SceneObject = sceneObject, Data = element }; _activeElements.Add(instance); var elementTransition = frameTransition; if (element.OverrideTransition != null) { elementTransition = element.OverrideTransition[indexOfTransition]; } _animations.Add(elementTransition.TransitionNewSceneObjectIn(sceneObject)); } } foreach (var anim in _animations) { anim.OnStart(); } var duration = frameTransition.GetTime(); if (duration > 0) { // Using enumerator for non-instant animations var started = Time.time; while (true) { var timeSinceStart = Time.time - started; if (timeSinceStart > duration) { break; } var progress = 0f; if (duration > 0) { progress = Mathf.Clamp01(timeSinceStart / duration); } foreach (var anim in _animations) { anim.OnUpdate(progress); } yield return(null); } } else { // Instant animations complete in a single frame foreach (var anim in _animations) { anim.OnUpdate(1f); } } foreach (var anim in _animations) { anim.OnCompleted(); } foreach (var element in oldElements) { Destroy(element.SceneObject); element.Data = null; } _activeElements.RemoveAll(el => el.Data == null); _activeFrameData = frameData; _animations.Clear(); }