Example #1
0
        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();
        }