Exemplo n.º 1
0
    public override void Reset()
    {
        base.Reset();
        if (state_Boss == null)
        {
            return;
        }
        gameEnd = false;

        StopAllCoroutines();
        state_Boss.SetEmptyAnimation(0, 0);
        var tarck = state_Boss.AddAnimation(0, enterTalking, false, 0);

        tarck.TimeScale = 0;

        bossElectricity.Power = 0;
        bossFireProjectile.Stop();
        missileLauncher.Reset();
        obj_WarningUI.SetActive(false);

        DOTween.Complete(spine_Boss.transform);
        spine_Boss.transform.position = bossStartPos;

        AudioController.StopCategory("Boss00");
        AudioController.SetCategoryVolume("Boss00", 1f);
        AudioController.SetCategoryVolume("Sfx", 1f);
        Time.timeScale = 1f;
    }
Exemplo n.º 2
0
    public override void Reset()
    {
        if (state_Boss == null)
        {
            return;
        }
        gameEnd = false;

        //LogManager.Log("Go = Restart");

        spine_Boss.gameObject.SetActive(true);
        spine_BossAttack.gameObject.SetActive(false);
        spine_BossDamage.gameObject.SetActive(false);
        spine_BossDie.gameObject.SetActive(false);

        state_Boss.SetEmptyAnimation(0, 0);
        var tarck = state_Boss.AddAnimation(0, enterTalk, false, 0);

        tarck.TimeScale = 0;

        obj_electricity.SetActive(false);
        bossFireProjectile.Stop();
        missileLauncher.Reset();

        DOTween.Complete(spine_Boss.transform);
        spine_Boss.transform.position = bossStartPos;
    }
        public override void ProcessFrame(Playable playable, FrameData info, object playerData)
        {
            SkeletonAnimation spineComponent = playerData as SkeletonAnimation;

            if (spineComponent != null)
            {
                Skeleton             skeleton       = spineComponent.Skeleton;
                Spine.AnimationState animationState = spineComponent.AnimationState;
                if (!Application.isPlaying)
                {
                    this.PreviewEditModePose(playable, spineComponent);
                }
                else
                {
                    int inputCount = playable.GetInputCount <Playable>();
                    if ((this.lastInputWeights == null) || (this.lastInputWeights.Length < inputCount))
                    {
                        this.lastInputWeights = new float[inputCount];
                        for (int j = 0; j < inputCount; j++)
                        {
                            this.lastInputWeights[j] = 0f;
                        }
                    }
                    float[] lastInputWeights = this.lastInputWeights;
                    for (int i = 0; i < inputCount; i++)
                    {
                        float num4        = lastInputWeights[i];
                        float inputWeight = playable.GetInputWeight <Playable>(i);
                        bool  flag        = inputWeight > num4;
                        lastInputWeights[i] = inputWeight;
                        if (flag)
                        {
                            SpineAnimationStateBehaviour behaviour = ((ScriptPlayable <SpineAnimationStateBehaviour>)playable.GetInput <Playable>(i)).GetBehaviour();
                            if (behaviour.animationReference == null)
                            {
                                float mixDuration = !behaviour.customDuration ? animationState.Data.DefaultMix : behaviour.mixDuration;
                                animationState.SetEmptyAnimation(0, mixDuration);
                            }
                            else if (behaviour.animationReference.Animation != null)
                            {
                                TrackEntry entry = animationState.SetAnimation(0, behaviour.animationReference.Animation, behaviour.loop);
                                entry.EventThreshold      = behaviour.eventThreshold;
                                entry.DrawOrderThreshold  = behaviour.drawOrderThreshold;
                                entry.AttachmentThreshold = behaviour.attachmentThreshold;
                                if (behaviour.customDuration)
                                {
                                    entry.MixDuration = behaviour.mixDuration;
                                }
                            }
                            spineComponent.Update(0f);
                            spineComponent.LateUpdate();
                        }
                    }
                }
            }
        }
Exemplo n.º 4
0
 static int SetEmptyAnimation(IntPtr L)
 {
     try
     {
         ToLua.CheckArgsCount(L, 3);
         Spine.AnimationState obj = (Spine.AnimationState)ToLua.CheckObject(L, 1, typeof(Spine.AnimationState));
         int              arg0    = (int)LuaDLL.luaL_checknumber(L, 2);
         float            arg1    = (float)LuaDLL.luaL_checknumber(L, 3);
         Spine.TrackEntry o       = obj.SetEmptyAnimation(arg0, arg1);
         ToLua.PushObject(L, o);
         return(1);
     }
     catch (Exception e)
     {
         return(LuaDLL.toluaL_exception(L, e));
     }
 }
Exemplo n.º 5
0
    private IEnumerator ClearAnim(float transition)
    {
        float timer = 0;

        while (timer <= transition)
        {
            yield return(new WaitForFixedUpdate());

            while (!CharOwner.VFXTestMode && (BattleManagerScript.Instance.CurrentBattleState == BattleState.Pause))
            {
                yield return(new WaitForEndOfFrame());
            }
            timer += Time.fixedDeltaTime;
        }
        Debug.Log("Clear");
        SpineAnimationState.SetEmptyAnimation(0, 0);
    }
Exemplo n.º 6
0
        AnimationStateTests(string testJsonFilePath)
        {
            skeletonData = json.ReadSkeletonData(testJsonFilePath);

            TrackEntry entry;

            Setup("0.1 time step",                   // 1
                  Expect(0, "start", 0, 0),          //
                  Expect(0, "event 0", 0, 0),        //
                  Expect(0, "event 14", 0.5f, 0.5f), //
                  Expect(0, "event 30", 1, 1),       //
                  Expect(0, "complete", 1, 1),       //
                  Expect(0, "end", 1, 1.1f),         //
                  Expect(0, "dispose", 1, 1.1f)      //
                  );
            state.SetAnimation(0, "events0", false).TrackEnd = 1;
            Run(0.1f, 1000, null);

            Setup("1/60 time step, dispose queued",     // 2
                  Expect(0, "start", 0, 0),             //
                  Expect(0, "interrupt", 0, 0),         //
                  Expect(0, "end", 0, 0),               //
                  Expect(0, "dispose", 0, 0),           //
                  Expect(1, "dispose", 0, 0),           //
                  Expect(0, "dispose", 0, 0),           //
                  Expect(1, "dispose", 0, 0),           //

                  Note("First 2 set/addAnimation calls are done."),

                  Expect(0, "start", 0, 0),               //
                  Expect(0, "event 0", 0, 0),             //
                  Expect(0, "event 14", 0.483f, 0.483f),  //
                  Expect(0, "event 30", 1, 1),            //
                  Expect(0, "complete", 1, 1),            //
                  Expect(0, "end", 1, 1.017f),            //
                  Expect(0, "dispose", 1, 1.017f)         //
                  );
            state.SetAnimation(0, "events0", false);
            state.AddAnimation(0, "events1", false, 0);
            state.AddAnimation(0, "events0", false, 0);
            state.AddAnimation(0, "events1", false, 0);
            state.SetAnimation(0, "events0", false).TrackEnd = 1;
            Run(1 / 60f, 1000, null);

            Setup("30 time step",                // 3
                  Expect(0, "start", 0, 0),      //
                  Expect(0, "event 0", 0, 0),    //
                  Expect(0, "event 14", 30, 30), //
                  Expect(0, "event 30", 30, 30), //
                  Expect(0, "complete", 30, 30), //
                  Expect(0, "end", 30, 60),      //
                  Expect(0, "dispose", 30, 60)   //
                  );
            state.SetAnimation(0, "events0", false).TrackEnd = 1;
            Run(30, 1000, null);

            Setup("1 time step",               // 4
                  Expect(0, "start", 0, 0),    //
                  Expect(0, "event 0", 0, 0),  //
                  Expect(0, "event 14", 1, 1), //
                  Expect(0, "event 30", 1, 1), //
                  Expect(0, "complete", 1, 1), //
                  Expect(0, "end", 1, 2),      //
                  Expect(0, "dispose", 1, 2)   //
                  );
            state.SetAnimation(0, "events0", false).TrackEnd = 1;
            Run(1, 1.01f, null);

            Setup("interrupt",                        // 5
                  Expect(0, "start", 0, 0),           //
                  Expect(0, "event 0", 0, 0),         //
                  Expect(0, "event 14", 0.5f, 0.5f),  //
                  Expect(0, "event 30", 1, 1),        //
                  Expect(0, "complete", 1, 1),        //
                  Expect(0, "interrupt", 1.1f, 1.1f), //

                  Expect(1, "start", 0.1f, 1.1f),     //
                  Expect(1, "event 0", 0.1f, 1.1f),   //

                  Expect(0, "end", 1.1f, 1.2f),       //
                  Expect(0, "dispose", 1.1f, 1.2f),   //

                  Expect(1, "event 14", 0.5f, 1.5f),  //
                  Expect(1, "event 30", 1, 2),        //
                  Expect(1, "complete", 1, 2),        //
                  Expect(1, "interrupt", 1.1f, 2.1f), //

                  Expect(0, "start", 0.1f, 2.1f),     //
                  Expect(0, "event 0", 0.1f, 2.1f),   //

                  Expect(1, "end", 1.1f, 2.2f),       //
                  Expect(1, "dispose", 1.1f, 2.2f),   //

                  Expect(0, "event 14", 0.5f, 2.5f),  //
                  Expect(0, "event 30", 1, 3),        //
                  Expect(0, "complete", 1, 3),        //
                  Expect(0, "end", 1, 3.1f),          //
                  Expect(0, "dispose", 1, 3.1f)       //
                  );
            state.SetAnimation(0, "events0", false);
            state.AddAnimation(0, "events1", false, 0);
            state.AddAnimation(0, "events0", false, 0).TrackEnd = 1;
            Run(0.1f, 4f, null);

            Setup("interrupt with delay",             // 6
                  Expect(0, "start", 0, 0),           //
                  Expect(0, "event 0", 0, 0),         //
                  Expect(0, "event 14", 0.5f, 0.5f),  //
                  Expect(0, "interrupt", 0.6f, 0.6f), //

                  Expect(1, "start", 0.1f, 0.6f),     //
                  Expect(1, "event 0", 0.1f, 0.6f),   //

                  Expect(0, "end", 0.6f, 0.7f),       //
                  Expect(0, "dispose", 0.6f, 0.7f),   //

                  Expect(1, "event 14", 0.5f, 1.0f),  //
                  Expect(1, "event 30", 1, 1.5f),     //
                  Expect(1, "complete", 1, 1.5f),     //
                  Expect(1, "end", 1, 1.6f),          //
                  Expect(1, "dispose", 1, 1.6f)       //
                  );
            state.SetAnimation(0, "events0", false);
            state.AddAnimation(0, "events1", false, 0.5f).TrackEnd = 1;
            Run(0.1f, 1000, null);

            Setup("interrupt with delay and mix time",  // 7
                  Expect(0, "start", 0, 0),             //
                  Expect(0, "event 0", 0, 0),           //
                  Expect(0, "event 14", 0.5f, 0.5f),    //
                  Expect(0, "interrupt", 1, 1),         //

                  Expect(1, "start", 0.1f, 1),          //

                  Expect(0, "complete", 1, 1),          //

                  Expect(1, "event 0", 0.1f, 1),        //
                  Expect(1, "event 14", 0.5f, 1.4f),    //

                  Expect(0, "end", 1.6f, 1.7f),         //
                  Expect(0, "dispose", 1.6f, 1.7f),     //

                  Expect(1, "event 30", 1, 1.9f),       //
                  Expect(1, "complete", 1, 1.9f),       //
                  Expect(1, "end", 1, 2),               //
                  Expect(1, "dispose", 1, 2)            //
                  );
            stateData.SetMix("events0", "events1", 0.7f);
            state.SetAnimation(0, "events0", true);
            state.AddAnimation(0, "events1", false, 0.9f).TrackEnd = 1;
            Run(0.1f, 1000, null);

            Setup("animation 0 events do not fire during mix", // 8
                  Expect(0, "start", 0, 0),                    //
                  Expect(0, "event 0", 0, 0),                  //
                  Expect(0, "interrupt", 0.5f, 0.5f),          //

                  Expect(1, "start", 0.1f, 0.5f),              //
                  Expect(1, "event 0", 0.1f, 0.5f),            //
                  Expect(1, "event 14", 0.5f, 0.9f),           //

                  Expect(0, "complete", 1, 1),                 //
                  Expect(0, "end", 1.1f, 1.2f),                //
                  Expect(0, "dispose", 1.1f, 1.2f),            //

                  Expect(1, "event 30", 1, 1.4f),              //
                  Expect(1, "complete", 1, 1.4f),              //
                  Expect(1, "end", 1, 1.5f),                   //
                  Expect(1, "dispose", 1, 1.5f)                //
                  );
            stateData.DefaultMix = 0.7f;
            state.SetAnimation(0, "events0", false);
            state.AddAnimation(0, "events1", false, 0.4f).TrackEnd = 1;
            Run(0.1f, 1000, null);

            Setup("event threshold, some animation 0 events fire during mix", // 9
                  Expect(0, "start", 0, 0),                                   //
                  Expect(0, "event 0", 0, 0),                                 //
                  Expect(0, "interrupt", 0.5f, 0.5f),                         //

                  Expect(1, "start", 0.1f, 0.5f),                             //

                  Expect(0, "event 14", 0.5f, 0.5f),                          //

                  Expect(1, "event 0", 0.1f, 0.5f),                           //
                  Expect(1, "event 14", 0.5f, 0.9f),                          //

                  Expect(0, "complete", 1, 1),                                //
                  Expect(0, "end", 1.1f, 1.2f),                               //
                  Expect(0, "dispose", 1.1f, 1.2f),                           //

                  Expect(1, "event 30", 1, 1.4f),                             //
                  Expect(1, "complete", 1, 1.4f),                             //
                  Expect(1, "end", 1, 1.5f),                                  //
                  Expect(1, "dispose", 1, 1.5f)                               //
                  );
            stateData.SetMix("events0", "events1", 0.7f);
            state.SetAnimation(0, "events0", false).EventThreshold = 0.5f;
            state.AddAnimation(0, "events1", false, 0.4f).TrackEnd = 1;
            Run(0.1f, 1000, null);

            Setup("event threshold, all animation 0 events fire during mix", // 10
                  Expect(0, "start", 0, 0),                                  //
                  Expect(0, "event 0", 0, 0),                                //
                  Expect(0, "event 14", 0.5f, 0.5f),                         //
                  Expect(0, "interrupt", 0.9f, 0.9f),                        //

                  Expect(1, "start", 0.1f, 0.9f),                            //
                  Expect(1, "event 0", 0.1f, 0.9f),                          //

                  Expect(0, "event 30", 1, 1),                               //
                  Expect(0, "complete", 1, 1),                               //
                  Expect(0, "event 0", 1, 1),                                //

                  Expect(1, "event 14", 0.5f, 1.3f),                         //

                  Expect(0, "end", 1.5f, 1.6f),                              //
                  Expect(0, "dispose", 1.5f, 1.6f),                          //

                  Expect(1, "event 30", 1, 1.8f),                            //
                  Expect(1, "complete", 1, 1.8f),                            //
                  Expect(1, "end", 1, 1.9f),                                 //
                  Expect(1, "dispose", 1, 1.9f)                              //
                  );
            state.SetAnimation(0, "events0", true).EventThreshold = 1;
            entry             = state.AddAnimation(0, "events1", false, 0.8f);
            entry.MixDuration = 0.7f;
            entry.TrackEnd    = 1;
            Run(0.1f, 1000, null);

            Setup("looping",                         // 11
                  Expect(0, "start", 0, 0),          //
                  Expect(0, "event 0", 0, 0),        //
                  Expect(0, "event 14", 0.5f, 0.5f), //
                  Expect(0, "event 30", 1, 1),       //
                  Expect(0, "complete", 1, 1),       //
                  Expect(0, "event 0", 1, 1),        //
                  Expect(0, "event 14", 1.5f, 1.5f), //
                  Expect(0, "event 30", 2, 2),       //
                  Expect(0, "complete", 2, 2),       //
                  Expect(0, "event 0", 2, 2),        //
                  Expect(0, "event 14", 2.5f, 2.5f), //
                  Expect(0, "event 30", 3, 3),       //
                  Expect(0, "complete", 3, 3),       //
                  Expect(0, "event 0", 3, 3),        //
                  Expect(0, "event 14", 3.5f, 3.5f), //
                  Expect(0, "event 30", 4, 4),       //
                  Expect(0, "complete", 4, 4),       //
                  Expect(0, "event 0", 4, 4),        //
                  Expect(0, "end", 4.1f, 4.1f),      //
                  Expect(0, "dispose", 4.1f, 4.1f)   //
                  );
            state.SetAnimation(0, "events0", true);
            Run(0.1f, 4, null);

            Setup("not looping, track end past animation 0 duration", // 12
                  Expect(0, "start", 0, 0),                           //
                  Expect(0, "event 0", 0, 0),                         //
                  Expect(0, "event 14", 0.5f, 0.5f),                  //
                  Expect(0, "event 30", 1, 1),                        //
                  Expect(0, "complete", 1, 1),                        //
                  Expect(0, "interrupt", 2.1f, 2.1f),                 //

                  Expect(1, "start", 0.1f, 2.1f),                     //
                  Expect(1, "event 0", 0.1f, 2.1f),                   //

                  Expect(0, "end", 2.1f, 2.2f),                       //
                  Expect(0, "dispose", 2.1f, 2.2f),                   //

                  Expect(1, "event 14", 0.5f, 2.5f),                  //
                  Expect(1, "event 30", 1, 3),                        //
                  Expect(1, "complete", 1, 3),                        //
                  Expect(1, "end", 1, 3.1f),                          //
                  Expect(1, "dispose", 1, 3.1f)                       //
                  );
            state.SetAnimation(0, "events0", false);
            state.AddAnimation(0, "events1", false, 2).TrackEnd = 1;
            Run(0.1f, 4f, null);


            Setup("interrupt animation after first loop complete", // 13
                  Expect(0, "start", 0, 0),                        //
                  Expect(0, "event 0", 0, 0),                      //
                  Expect(0, "event 14", 0.5f, 0.5f),               //
                  Expect(0, "event 30", 1, 1),                     //
                  Expect(0, "complete", 1, 1),                     //
                  Expect(0, "event 0", 1, 1),                      //
                  Expect(0, "event 14", 1.5f, 1.5f),               //
                  Expect(0, "event 30", 2, 2),                     //
                  Expect(0, "complete", 2, 2),                     //
                  Expect(0, "event 0", 2, 2),                      //
                  Expect(0, "interrupt", 2.1f, 2.1f),              //

                  Expect(1, "start", 0.1f, 2.1f),                  //
                  Expect(1, "event 0", 0.1f, 2.1f),                //

                  Expect(0, "end", 2.1f, 2.2f),                    //
                  Expect(0, "dispose", 2.1f, 2.2f),                //

                  Expect(1, "event 14", 0.5f, 2.5f),               //
                  Expect(1, "event 30", 1, 3),                     //
                  Expect(1, "complete", 1, 3),                     //
                  Expect(1, "end", 1, 3.1f),                       //
                  Expect(1, "dispose", 1, 3.1f)                    //
                  );
            state.SetAnimation(0, "events0", true);
            Run(0.1f, 6, new TestListener(
                    (time) => {
                if (IsEqual(time, 1.4f))
                {
                    state.AddAnimation(0, "events1", false, 0).TrackEnd = 1;
                }
            }));

            Setup("add animation on empty track",         // 14
                  Expect(0, "start", 0, 0),               //
                  Expect(0, "event 0", 0, 0),             //
                  Expect(0, "event 14", 0.5f, 0.5f),      //
                  Expect(0, "event 30", 1, 1),            //
                  Expect(0, "complete", 1, 1),            //
                  Expect(0, "end", 1, 1.1f),              //
                  Expect(0, "dispose", 1, 1.1f)           //
                  );
            state.AddAnimation(0, "events0", false, 0).TrackEnd = 1;
            Run(0.1f, 1.9f, null);

            Setup("end time beyond non-looping animation duration", // 15
                  Expect(0, "start", 0, 0),                         //
                  Expect(0, "event 0", 0, 0),                       //
                  Expect(0, "event 14", 0.5f, 0.5f),                //
                  Expect(0, "event 30", 1, 1),                      //
                  Expect(0, "complete", 1, 1),                      //
                  Expect(0, "end", 9f, 9.1f),                       //
                  Expect(0, "dispose", 9f, 9.1f)                    //
                  );
            state.SetAnimation(0, "events0", false).TrackEnd = 9;
            Run(0.1f, 10, null);

            Setup("looping with animation start",         // 16
                  Expect(0, "start", 0, 0),               //
                  Expect(0, "event 30", 0.4f, 0.4f),      //
                  Expect(0, "complete", 0.4f, 0.4f),      //
                  Expect(0, "event 30", 0.8f, 0.8f),      //
                  Expect(0, "complete", 0.8f, 0.8f),      //
                  Expect(0, "event 30", 1.2f, 1.2f),      //
                  Expect(0, "complete", 1.2f, 1.2f),      //
                  Expect(0, "end", 1.4f, 1.4f),           //
                  Expect(0, "dispose", 1.4f, 1.4f)        //
                  );
            entry = state.SetAnimation(0, "events0", true);
            entry.AnimationLast  = 0.6f;
            entry.AnimationStart = 0.6f;
            Run(0.1f, 1.4f, null);

            Setup("looping with animation start and end", // 17
                  Expect(0, "start", 0, 0),               //
                  Expect(0, "event 14", 0.3f, 0.3f),      //
                  Expect(0, "complete", 0.6f, 0.6f),      //
                  Expect(0, "event 14", 0.9f, 0.9f),      //
                  Expect(0, "complete", 1.2f, 1.2f),      //
                  Expect(0, "event 14", 1.5f, 1.5f),      //
                  Expect(0, "end", 1.8f, 1.8f),           //
                  Expect(0, "dispose", 1.8f, 1.8f)        //
                  );
            entry = state.SetAnimation(0, "events0", true);
            entry.AnimationStart = 0.2f;
            entry.AnimationLast  = 0.2f;
            entry.AnimationEnd   = 0.8f;
            Run(0.1f, 1.8f, null);

            Setup("non-looping with animation start and end", // 18
                  Expect(0, "start", 0, 0),                   //
                  Expect(0, "event 14", 0.3f, 0.3f),          //
                  Expect(0, "complete", 0.6f, 0.6f),          //
                  Expect(0, "end", 1, 1.1f),                  //
                  Expect(0, "dispose", 1, 1.1f)               //
                  );
            entry = state.SetAnimation(0, "events0", false);
            entry.AnimationStart = 0.2f;
            entry.AnimationLast  = 0.2f;
            entry.AnimationEnd   = 0.8f;
            entry.TrackEnd       = 1;
            Run(0.1f, 1.8f, null);

            Setup("mix out looping with animation start and end", // 19
                  Expect(0, "start", 0, 0),                       //
                  Expect(0, "event 14", 0.3f, 0.3f),              //
                  Expect(0, "complete", 0.6f, 0.6f),              //
                  Expect(0, "interrupt", 0.8f, 0.8f),             //

                  Expect(1, "start", 0.1f, 0.8f),                 //
                  Expect(1, "event 0", 0.1f, 0.8f),               //

                  Expect(0, "event 14", 0.9f, 0.9f),              //
                  Expect(0, "complete", 1.2f, 1.2f),              //

                  Expect(1, "event 14", 0.5f, 1.2f),              //

                  Expect(0, "end", 1.4f, 1.5f),                   //
                  Expect(0, "dispose", 1.4f, 1.5f),               //

                  Expect(1, "event 30", 1, 1.7f),                 //
                  Expect(1, "complete", 1, 1.7f),                 //
                  Expect(1, "end", 1, 1.8f),                      //
                  Expect(1, "dispose", 1, 1.8f)                   //
                  );
            entry = state.SetAnimation(0, "events0", true);
            entry.AnimationStart = (0.2f);
            entry.AnimationLast  = (0.2f);
            entry.AnimationEnd   = (0.8f);
            entry.EventThreshold = 1;
            entry             = state.AddAnimation(0, "events1", false, 0.7f);
            entry.MixDuration = (0.7f);
            entry.TrackEnd    = 1;
            Run(0.1f, 20, null);

            Setup("setAnimation with track entry mix",    // 20
                  Expect(0, "start", 0, 0),               //
                  Expect(0, "event 0", 0, 0),             //
                  Expect(0, "event 14", 0.5f, 0.5f),      //
                  Expect(0, "event 30", 1, 1),            //
                  Expect(0, "complete", 1, 1),            //
                  Expect(0, "event 0", 1, 1),             //
                  Expect(0, "interrupt", 1, 1),           //

                  Expect(1, "start", 0, 1),               //

                  Expect(1, "event 0", 0.1f, 1.1f),       //
                  Expect(1, "event 14", 0.5f, 1.5f),      //

                  Expect(0, "end", 1.7f, 1.8f),           //
                  Expect(0, "dispose", 1.7f, 1.8f),       //

                  Expect(1, "event 30", 1, 2),            //
                  Expect(1, "complete", 1, 2),            //
                  Expect(1, "end", 1, 2.1f),              //
                  Expect(1, "dispose", 1, 2.1f)           //
                  );
            state.SetAnimation(0, "events0", true);
            Run(0.1f, 1000, new TestListener(
                    (time) => {
                if (IsEqual(time, 1f))
                {
                    TrackEntry ent  = state.SetAnimation(0, "events1", false);
                    ent.MixDuration = (0.7f);
                    ent.TrackEnd    = 1;
                }
            }));

            Setup("setAnimation twice",              // 21
                  Expect(0, "start", 0, 0),          //
                  Expect(0, "interrupt", 0, 0),      //
                  Expect(0, "end", 0, 0),            //
                  Expect(0, "dispose", 0, 0),        //

                  Expect(1, "start", 0, 0),          //
                  Expect(1, "event 0", 0, 0),        //
                  Expect(1, "event 14", 0.5f, 0.5f), //

                  Note("First 2 setAnimation calls are done."),

                  Expect(1, "interrupt", 0.8f, 0.8f),      //

                  Expect(0, "start", 0, 0.8f),             //
                  Expect(0, "interrupt", 0, 0.8f),         //
                  Expect(0, "end", 0, 0.8f),               //
                  Expect(0, "dispose", 0, 0.8f),           //

                  Expect(2, "start", 0, 0.8f),             //
                  Expect(2, "event 0", 0.1f, 0.9f),        //

                  Expect(1, "end", 0.9f, 1),               //
                  Expect(1, "dispose", 0.9f, 1),           //

                  Expect(2, "event 14", 0.5f, 1.3f),       //
                  Expect(2, "event 30", 1, 1.8f),          //
                  Expect(2, "complete", 1, 1.8f),          //
                  Expect(2, "end", 1, 1.9f),               //
                  Expect(2, "dispose", 1, 1.9f)            //
                  );
            state.SetAnimation(0, "events0", false);       // First should be ignored.
            state.SetAnimation(0, "events1", false);
            Run(0.1f, 1000, new TestListener(
                    (time) => {
                if (IsEqual(time, 0.8f))
                {
                    state.SetAnimation(0, "events0", false);                             // First should be ignored.
                    state.SetAnimation(0, "events2", false).TrackEnd = 1;
                }
            }));

            Setup("setAnimation twice with multiple mixing", // 22
                  Expect(0, "start", 0, 0),                  //
                  Expect(0, "interrupt", 0, 0),              //
                  Expect(0, "end", 0, 0),                    //
                  Expect(0, "dispose", 0, 0),                //

                  Expect(1, "start", 0, 0),                  //
                  Expect(1, "event 0", 0, 0),                //

                  Note("First 2 setAnimation calls are done."),

                  Expect(1, "interrupt", 0.2f, 0.2f),      //

                  Expect(0, "start", 0, 0.2f),             //
                  Expect(0, "interrupt", 0, 0.2f),         //
                  Expect(0, "end", 0, 0.2f),               //
                  Expect(0, "dispose", 0, 0.2f),           //

                  Expect(2, "start", 0, 0.2f),             //
                  Expect(2, "event 0", 0.1f, 0.3f),        //

                  Note("Second 2 setAnimation calls are done."),

                  Expect(2, "interrupt", 0.2f, 0.4f),      //

                  Expect(1, "start", 0, 0.4f),             //
                  Expect(1, "interrupt", 0, 0.4f),         //
                  Expect(1, "end", 0, 0.4f),               //
                  Expect(1, "dispose", 0, 0.4f),           //

                  Expect(0, "start", 0, 0.4f),             //
                  Expect(0, "event 0", 0.1f, 0.5f),        //

                  Expect(1, "end", 0.8f, 0.9f),            //
                  Expect(1, "dispose", 0.8f, 0.9f),        //

                  Expect(0, "event 14", 0.5f, 0.9f),       //

                  Expect(2, "end", 0.8f, 1.1f),            //
                  Expect(2, "dispose", 0.8f, 1.1f),        //

                  Expect(0, "event 30", 1, 1.4f),          //
                  Expect(0, "complete", 1, 1.4f),          //
                  Expect(0, "end", 1, 1.5f),               //
                  Expect(0, "dispose", 1, 1.5f)            //
                  );
            stateData.DefaultMix = 0.6f;
            state.SetAnimation(0, "events0", false);             // First should be ignored.
            state.SetAnimation(0, "events1", false);
            Run(0.1f, 1000, new TestListener(
                    (time) => {
                if (IsEqual(time, 0.2f))
                {
                    state.SetAnimation(0, "events0", false);                             // First should be ignored.
                    state.SetAnimation(0, "events2", false);
                }
                if (IsEqual(time, 0.4f))
                {
                    state.SetAnimation(0, "events1", false);                             // First should be ignored.
                    state.SetAnimation(0, "events0", false).TrackEnd = 1;
                }
            }));

            Setup("addAnimation with delay on empty track", // 23
                  Expect(0, "start", 0, 0),                 //
                  Expect(0, "event 0", 0, 5),               //
                  Expect(0, "event 14", 0.5f, 5.5f),        //
                  Expect(0, "event 30", 1, 6),              //
                  Expect(0, "complete", 1, 6),              //
                  Expect(0, "end", 1, 6.1f),                //
                  Expect(0, "dispose", 1, 6.1f)             //
                  );
            state.AddAnimation(0, "events0", false, 5).TrackEnd = 1;
            Run(0.1f, 10, null);

            Setup("setAnimation during AnimationStateListener");             // 24
            state.Start += (trackEntry) => {
                if (trackEntry.Animation.Name.Equals("events0"))
                {
                    state.SetAnimation(1, "events1", false);
                }
            };
            state.Interrupt += (trackEntry) => {
                state.AddAnimation(3, "events1", false, 0);
            };
            state.End += (trackEntry) => {
                if (trackEntry.Animation.Name.Equals("events0"))
                {
                    state.SetAnimation(0, "events1", false);
                }
            };
            state.Dispose += (trackEntry) => {
                if (trackEntry.Animation.Name.Equals("events0"))
                {
                    state.SetAnimation(1, "events1", false);
                }
            };
            state.Complete += (trackEntry) => {
                if (trackEntry.Animation.Name.Equals("events0"))
                {
                    state.SetAnimation(1, "events1", false);
                }
            };
            state.Event += (trackEntry, ev) => {
                if (trackEntry.TrackIndex != 2)
                {
                    state.SetAnimation(2, "events1", false);
                }
            };
            state.AddAnimation(0, "events0", false, 0);
            state.AddAnimation(0, "events1", false, 0);
            state.SetAnimation(1, "events1", false).TrackEnd = 1;
            Run(0.1f, 10, null);

            Setup("clearTrack",                      // 25
                  Expect(0, "start", 0, 0),          //
                  Expect(0, "event 0", 0, 0),        //
                  Expect(0, "event 14", 0.5f, 0.5f), //
                  Expect(0, "end", 0.7f, 0.7f),      //
                  Expect(0, "dispose", 0.7f, 0.7f)   //
                  );
            state.AddAnimation(0, "events0", false, 0).TrackEnd = 1;
            Run(0.1f, 10, new TestListener(
                    (time) => {
                if (IsEqual(time, 0.7f))
                {
                    state.ClearTrack(0);
                }
            }));

            Setup("setEmptyAnimation",                // 26
                  Expect(0, "start", 0, 0),           //
                  Expect(0, "event 0", 0, 0),         //
                  Expect(0, "event 14", 0.5f, 0.5f),  //
                  Expect(0, "interrupt", 0.7f, 0.7f), //

                  Expect(-1, "start", 0, 0.7f),       //
                  Expect(-1, "complete", 0.1f, 0.8f), //

                  Expect(0, "end", 0.8f, 0.9f),       //
                  Expect(0, "dispose", 0.8f, 0.9f),   //

                  Expect(-1, "end", 0.2f, 1),         //
                  Expect(-1, "dispose", 0.2f, 1)      //
                  );
            state.AddAnimation(0, "events0", false, 0).TrackEnd = 1;
            Run(0.1f, 10, new TestListener(
                    (time) => {
                if (IsEqual(time, 0.7f))
                {
                    state.SetEmptyAnimation(0, 0);
                }
            }));

            Setup("TrackEntry listener");             // 27
            int counter = 0;

            entry        = state.AddAnimation(0, "events0", false, 0);
            entry.Start += (trackEntry) => {
                Interlocked.Add(ref counter, 1 << 1);
            };
            entry.Interrupt += (trackEntry) => {
                Interlocked.Add(ref counter, 1 << 5);
            };
            entry.End += (trackEntry) => {
                Interlocked.Add(ref counter, 1 << 9);
            };
            entry.Dispose += (trackEntry) => {
                Interlocked.Add(ref counter, 1 << 13);
            };
            entry.Complete += (trackEntry) => {
                Interlocked.Add(ref counter, 1 << 17);
            };
            entry.Event += (trackEntry, ev) => {
                Interlocked.Add(ref counter, 1 << 21);
            };
            state.AddAnimation(0, "events0", false, 0);
            state.AddAnimation(0, "events1", false, 0);
            state.SetAnimation(1, "events1", false).TrackEnd = 1;
            Run(0.1f, 10, null);
            if (counter != 15082016)
            {
                string message = "TEST 27 FAILED! " + counter;
                Log(message);
                FailTestRun(message);
            }

#if RUN_ADDITIONAL_FORUM_RELATED_TEST
            Setup("0.1 time step, start and add",         // 2
                  Expect(0, "start", 0, 0),               //
                  Expect(0, "event 0", 0, 0),             //
                  Expect(0, "event 14", 0.5f, 0.5f),      //
                  Expect(0, "event 30", 1, 1),            //
                  Expect(0, "complete", 1, 1),            //
                  Expect(0, "interrupt", 1.1f, 1.1f),     //
                  Expect(1, "start", 0.1f, 1.1f),         //
                  Expect(1, "event 0", 0.1f, 1.1f),       //
                  Expect(0, "end", 1.3f, 1.4f),           //
                  Expect(0, "dispose", 1.3f, 1.4f),       //
                  Expect(1, "event 14", 0.5f, 1.5f),      //
                  Expect(1, "event 30", 1, 2),            //
                  Expect(1, "complete", 1, 2),            //
                  Expect(1, "end", 1, 2.1f),              //
                  Expect(1, "dispose", 1, 2.1f)           //
                  );
            state.SetAnimation(0, "events0", false);
            var entry1 = state.AddAnimation(0, "events1", false, 0);
            entry1.MixDuration = 0.25f;
            entry1.TrackEnd    = 1.0f;
            Run(0.1f, 1000, null);
#endif // RUN_ADDITIONAL_FORUM_RELATED_TEST

            Log("AnimationState tests passed.");
        }
        /// <summary>
        /// Prepare a fragment of AnimationState that blends to produce the current timeline state.
        /// </summary>
        private AnimationState InitializeAnimationState(Playable playable, object playerData)
        {
            bool firstTime = affectedSkeletonAnimation == null && affectedSkeletonGraphic == null;

            if (firstTime)
            {
                var skeletonAnimation    = playerData as SkeletonAnimation;
                var skeletonGraphic      = playerData as SkeletonGraphic;
                var hasSkeletonDataAsset = playerData as IHasSkeletonDataAsset;

                //Make this once and keep clearing it instead.
                //This implies we will not ever change skeleton data mid-timeline. (unlikely?)
                animationState    = new AnimationState(hasSkeletonDataAsset.SkeletonDataAsset.GetAnimationStateData());
                isSkeletonGraphic = skeletonGraphic != null;
                if (!isSkeletonGraphic)
                {
                    affectedSkeletonAnimation = skeletonAnimation;
                    //Prevent regular update from interfering.
                    originalFreezeState       = skeletonAnimation.enabled;
                    skeletonAnimation.enabled = false;
                }
                else
                {
                    affectedSkeletonGraphic = skeletonGraphic;
                    //Prevent regular update from interfering.
                    originalFreezeState    = skeletonGraphic.freeze;
                    skeletonGraphic.freeze = true;
                }
            }

            animationState.SetEmptyAnimation(trackIndex, mixDuration: 0);

            // Find at most 2 blended clips that is affecting the playhead.
            // Spine could mix 3 clips but timeline's interface allows only 2 naturally.

            int  inputCount  = playable.GetInputCount();
            bool foundFirst  = false;
            bool foundSecond = false;

            for (int i = 0; i < inputCount; i++)
            {
                float inputWeight = playable.GetInputWeight(i);
                if (inputWeight == 0)
                {
                    continue;
                }

                ScriptPlayable <SpineTimelineClipBehaviour> clip = (ScriptPlayable <SpineTimelineClipBehaviour>)playable.GetInput(i);
                SpineTimelineClipBehaviour clipData = clip.GetBehaviour();
                var playheadFromClipBegin           = clip.GetTime();
                var clipDuration = clip.GetDuration();
                if (clipData.animationReference == null)
                {
                    continue;
                }

                Animation toAdd = clipData.animationReference.Animation;

                //Debug.Log($"{i} {playheadFromClipBegin} {inputWeight} {toAdd.Name} {toAdd.Duration}");

                if (!foundFirst)
                {
                    TrackEntry entry = animationState.SetAnimation(trackIndex, toAdd, clipData.loop);
                    entry.TrackTime = (float)playheadFromClipBegin;
                    entry.AllowImmediateQueue();
                    foundFirst = true;
                }
                else if (!foundSecond)
                {
                    //WIP? Apparently this produces a weird mix, I am not sure it is correct or not.
                    TrackEntry entry = animationState.SetAnimation(trackIndex, toAdd, clipData.loop);
                    entry.MixTime     = (float)playheadFromClipBegin;
                    entry.MixDuration = 1f;
                    foundSecond       = true;
                    break;
                }
            }

            return(animationState);
        }