// NOTE: This function is called at runtime and edit time. Keep that in mind when setting the values of properties.
		public override void ProcessFrame (Playable playable, FrameData info, object playerData) {
			var spineComponent = playerData as SkeletonAnimation;
			if (spineComponent == null) return;

			var skeleton = spineComponent.Skeleton;
			var state = spineComponent.AnimationState;

			if (!Application.isPlaying) {
				#if SPINE_EDITMODEPOSE
				PreviewEditModePose(playable, spineComponent);
				#endif
				return;
			}

			int inputCount = playable.GetInputCount();

			// Ensure correct buffer size.
			if (this.lastInputWeights == null || this.lastInputWeights.Length < inputCount) {
				this.lastInputWeights = new float[inputCount];

				for (int i = 0; i < inputCount; i++)
					this.lastInputWeights[i] = default(float);				
			}
			var lastInputWeights = this.lastInputWeights;

			// Check all clips. If a clip that was weight 0 turned into weight 1, call SetAnimation.
			for (int i = 0; i < inputCount; i++) {
				float lastInputWeight = lastInputWeights[i];
				float inputWeight = playable.GetInputWeight(i);
				bool trackStarted = inputWeight > lastInputWeight;
				lastInputWeights[i] = inputWeight;

				if (trackStarted) {
					ScriptPlayable<SpineAnimationStateBehaviour> inputPlayable = (ScriptPlayable<SpineAnimationStateBehaviour>)playable.GetInput(i);
					SpineAnimationStateBehaviour clipData = inputPlayable.GetBehaviour();

					if (clipData.animationReference == null) {
						float mixDuration = clipData.customDuration ? clipData.mixDuration : state.Data.DefaultMix;
						state.SetEmptyAnimation(trackIndex, mixDuration);
					} else {
						if (clipData.animationReference.Animation != null) {
							Spine.TrackEntry trackEntry = state.SetAnimation(trackIndex, clipData.animationReference.Animation, clipData.loop);

							//trackEntry.TrackTime = (float)inputPlayable.GetTime(); // More accurate time-start?
							trackEntry.EventThreshold = clipData.eventThreshold;
							trackEntry.DrawOrderThreshold = clipData.drawOrderThreshold;
							trackEntry.AttachmentThreshold = clipData.attachmentThreshold;

							if (clipData.customDuration)
								trackEntry.MixDuration = clipData.mixDuration;
						}
						//else Debug.LogWarningFormat("Animation named '{0}' not found", clipData.animationName);
					}

					// Ensure that the first frame ends with an updated mesh.
					spineComponent.Update(0);
					spineComponent.LateUpdate();
				}
			}
		}
 public void PreviewEditModePose(Playable playable, SkeletonAnimation spineComponent)
 {
     if (!Application.isPlaying && (spineComponent != null))
     {
         int inputCount = playable.GetInputCount <Playable>();
         int inputPort  = -1;
         for (int i = 0; i < inputCount; i++)
         {
             if (playable.GetInputWeight <Playable>(i) >= 1f)
             {
                 inputPort = i;
             }
         }
         if (inputPort != -1)
         {
             ScriptPlayable <SpineAnimationStateBehaviour> input = (ScriptPlayable <SpineAnimationStateBehaviour>)playable.GetInput <Playable>(inputPort);
             SpineAnimationStateBehaviour behaviour = input.GetBehaviour();
             Skeleton skeleton = spineComponent.Skeleton;
             if ((behaviour.animationReference != null) && (spineComponent.SkeletonDataAsset.GetSkeletonData(true) != behaviour.animationReference.SkeletonDataAsset.GetSkeletonData(true)))
             {
                 object[] args = new object[] { spineComponent.SkeletonDataAsset, behaviour.animationReference.SkeletonDataAsset };
                 Debug.LogWarningFormat("SpineAnimationStateMixerBehaviour tried to apply an animation for the wrong skeleton. Expected {0}. Was {1}", args);
             }
             Spine.Animation from = null;
             float           time = 0f;
             bool            loop = false;
             if ((inputPort != 0) && (inputCount > 1))
             {
                 ScriptPlayable <SpineAnimationStateBehaviour> playable3 = (ScriptPlayable <SpineAnimationStateBehaviour>)playable.GetInput <Playable>((inputPort - 1));
                 SpineAnimationStateBehaviour behaviour2 = playable3.GetBehaviour();
                 from = behaviour2.animationReference.Animation;
                 time = (float)playable3.GetTime <ScriptPlayable <SpineAnimationStateBehaviour> >();
                 loop = behaviour2.loop;
             }
             Spine.Animation animation   = behaviour.animationReference.Animation;
             float           num6        = (float)input.GetTime <ScriptPlayable <SpineAnimationStateBehaviour> >();
             float           mixDuration = behaviour.mixDuration;
             if (!behaviour.customDuration && (from != null))
             {
                 mixDuration = spineComponent.AnimationState.Data.GetMix(from, animation);
             }
             if (((from != null) && (mixDuration > 0f)) && (num6 < mixDuration))
             {
                 skeleton.SetToSetupPose();
                 float alpha = 1f - (num6 / mixDuration);
                 alpha = (alpha <= 0.5f) ? (alpha * 2f) : 1f;
                 from.Apply(skeleton, 0f, time, loop, null, alpha, MixPose.Setup, MixDirection.Out);
                 animation.Apply(skeleton, 0f, num6, behaviour.loop, null, num6 / mixDuration, MixPose.Current, MixDirection.In);
             }
             else
             {
                 skeleton.SetToSetupPose();
                 animation.PoseSkeleton(skeleton, num6, behaviour.loop);
             }
         }
     }
 }
        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();
                        }
                    }
                }
            }
        }
 float GetCustomMixDuration(SpineAnimationStateBehaviour clipData)
 {
     if (clipData.useBlendDuration)
     {
         TimelineClip clip = clipData.timelineClip;
         return((float)Math.Max(clip.blendInDuration, clip.easeInDuration));
     }
     else
     {
         return(clipData.mixDuration);
     }
 }
        public void PreviewEditModePose(Playable playable,
                                        ISkeletonComponent skeletonComponent, IAnimationStateComponent animationStateComponent,
                                        SkeletonAnimation skeletonAnimation, SkeletonGraphic skeletonGraphic)
        {
            if (Application.isPlaying)
            {
                return;
            }
            if (animationStateComponent.IsNullOrDestroyed() || skeletonComponent == null)
            {
                return;
            }

            int inputCount             = playable.GetInputCount();
            int lastNonZeroWeightTrack = -1;

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

            if (lastNonZeroWeightTrack != -1)
            {
                ScriptPlayable <SpineAnimationStateBehaviour> inputPlayableClip =
                    (ScriptPlayable <SpineAnimationStateBehaviour>)playable.GetInput(lastNonZeroWeightTrack);
                SpineAnimationStateBehaviour clipData = inputPlayableClip.GetBehaviour();

                var skeleton = skeletonComponent.Skeleton;

                bool skeletonDataMismatch = clipData.animationReference != null && clipData.animationReference.SkeletonDataAsset &&
                                            skeletonComponent.SkeletonDataAsset.GetSkeletonData(true) != clipData.animationReference.SkeletonDataAsset.GetSkeletonData(true);
                if (skeletonDataMismatch)
                {
                    Debug.LogWarningFormat("SpineAnimationStateMixerBehaviour tried to apply an animation for the wrong skeleton. Expected {0}. Was {1}",
                                           skeletonComponent.SkeletonDataAsset, clipData.animationReference.SkeletonDataAsset);
                }

                // Getting the from-animation here because it's required to get the mix information from AnimationStateData.
                Animation fromAnimation = null;
                float     fromClipTime  = 0;
                bool      fromClipLoop  = false;
                if (lastNonZeroWeightTrack != 0 && inputCount > 1)
                {
                    var fromClip     = (ScriptPlayable <SpineAnimationStateBehaviour>)playable.GetInput(lastNonZeroWeightTrack - 1);
                    var fromClipData = fromClip.GetBehaviour();
                    fromAnimation = fromClipData.animationReference != null ? fromClipData.animationReference.Animation : null;
                    fromClipTime  = (float)fromClip.GetTime() * (float)fromClip.GetSpeed();
                    fromClipLoop  = fromClipData.loop;
                }

                Animation toAnimation = clipData.animationReference != null ? clipData.animationReference.Animation : null;
                float     toClipTime  = (float)inputPlayableClip.GetTime() * (float)inputPlayableClip.GetSpeed();
                float     mixDuration = clipData.mixDuration;

                if (!clipData.customDuration && fromAnimation != null && toAnimation != null)
                {
                    mixDuration = animationStateComponent.AnimationState.Data.GetMix(fromAnimation, toAnimation);
                }

                if (trackIndex == 0)
                {
                    skeleton.SetToSetupPose();
                }

                // Approximate what AnimationState might do at runtime.
                if (fromAnimation != null && mixDuration > 0 && toClipTime < mixDuration)
                {
                    dummyAnimationState = dummyAnimationState ?? new AnimationState(skeletonComponent.SkeletonDataAsset.GetAnimationStateData());

                    var  toEntry   = dummyAnimationState.GetCurrent(0);
                    var  fromEntry = toEntry != null ? toEntry.MixingFrom : null;
                    bool isAnimationTransitionMatch = (toEntry != null && toEntry.Animation == toAnimation && fromEntry != null && fromEntry.Animation == fromAnimation);

                    if (!isAnimationTransitionMatch)
                    {
                        dummyAnimationState.ClearTracks();
                        fromEntry = dummyAnimationState.SetAnimation(0, fromAnimation, fromClipLoop);
                        fromEntry.AllowImmediateQueue();
                        if (toAnimation != null)
                        {
                            toEntry = dummyAnimationState.SetAnimation(0, toAnimation, clipData.loop);
                            toEntry.HoldPrevious = clipData.holdPrevious;
                        }
                    }

                    // Update track times.
                    fromEntry.TrackTime = fromClipTime;
                    if (toEntry != null)
                    {
                        toEntry.TrackTime = toClipTime;
                        toEntry.MixTime   = toClipTime;
                    }

                    // Apply Pose
                    dummyAnimationState.Update(0);
                    dummyAnimationState.Apply(skeleton);
                }
                else
                {
                    if (toAnimation != null)
                    {
                        toAnimation.Apply(skeleton, 0, toClipTime, clipData.loop, null, 1f, MixBlend.Setup, MixDirection.In);
                    }
                }
                skeleton.UpdateWorldTransform();

                if (skeletonAnimation)
                {
                    skeletonAnimation.LateUpdate();
                }
                else if (skeletonGraphic)
                {
                    skeletonGraphic.LateUpdate();
                }
            }
            // Do nothing outside of the first clip and the last clip.
        }
        // NOTE: This function is called at runtime and edit time. Keep that in mind when setting the values of properties.
        public override void ProcessFrame(Playable playable, FrameData info, object playerData)
        {
            var skeletonAnimation = playerData as SkeletonAnimation;
            var skeletonGraphic   = playerData as SkeletonGraphic;

            animationStateComponent = playerData as IAnimationStateComponent;
            var skeletonComponent = playerData as ISkeletonComponent;

            if (animationStateComponent.IsNullOrDestroyed() || skeletonComponent == null)
            {
                return;
            }

            var skeleton = skeletonComponent.Skeleton;
            var state    = animationStateComponent.AnimationState;

            if (!Application.isPlaying)
            {
#if SPINE_EDITMODEPOSE
                PreviewEditModePose(playable, skeletonComponent, animationStateComponent,
                                    skeletonAnimation, skeletonGraphic);
#endif
                return;
            }

            int inputCount = playable.GetInputCount();

            // Ensure correct buffer size.
            if (this.lastInputWeights == null || this.lastInputWeights.Length < inputCount)
            {
                this.lastInputWeights = new float[inputCount];

                for (int i = 0; i < inputCount; i++)
                {
                    this.lastInputWeights[i] = default(float);
                }
            }
            var  lastInputWeights = this.lastInputWeights;
            int  numStartingClips = 0;
            bool anyClipPlaying   = false;

            // Check all clips. If a clip that was weight 0 turned into weight 1, call SetAnimation.
            for (int i = 0; i < inputCount; i++)
            {
                float lastInputWeight = lastInputWeights[i];
                float inputWeight     = playable.GetInputWeight(i);
                bool  clipStarted     = lastInputWeight == 0 && inputWeight > 0;
                if (inputWeight > 0)
                {
                    anyClipPlaying = true;
                }
                lastInputWeights[i] = inputWeight;

                if (clipStarted && numStartingClips < 2)
                {
                    ScriptPlayable <SpineAnimationStateBehaviour> clipPlayable = (ScriptPlayable <SpineAnimationStateBehaviour>)playable.GetInput(i);
                    startingClips[numStartingClips++] = clipPlayable;
                }
            }
            // unfortunately order of clips can be wrong when two start at the same time, we have to sort clips
            if (numStartingClips == 2)
            {
                ScriptPlayable <SpineAnimationStateBehaviour> clipPlayable0 = startingClips[0];
                ScriptPlayable <SpineAnimationStateBehaviour> clipPlayable1 = startingClips[1];
                if (clipPlayable0.GetDuration() > clipPlayable1.GetDuration())                   // swap, clip 0 ends after clip 1
                {
                    startingClips[0] = clipPlayable1;
                    startingClips[1] = clipPlayable0;
                }
            }

            for (int j = 0; j < numStartingClips; ++j)
            {
                ScriptPlayable <SpineAnimationStateBehaviour> clipPlayable = startingClips[j];
                SpineAnimationStateBehaviour clipData = clipPlayable.GetBehaviour();
                pauseWithDirector = !clipData.dontPauseWithDirector;
                endAtClipEnd      = !clipData.dontEndWithClip;
                endMixOutDuration = clipData.endMixOutDuration;

                if (clipData.animationReference == null)
                {
                    float mixDuration = clipData.customDuration ? GetCustomMixDuration(clipData) : state.Data.DefaultMix;
                    state.SetEmptyAnimation(trackIndex, mixDuration);
                }
                else
                {
                    if (clipData.animationReference.Animation != null)
                    {
                        TrackEntry       currentEntry = state.GetCurrent(trackIndex);
                        Spine.TrackEntry trackEntry;
                        float            customMixDuration = clipData.customDuration ? GetCustomMixDuration(clipData) : 0.0f;
                        if (currentEntry == null && customMixDuration > 0)
                        {
                            state.SetEmptyAnimation(trackIndex, 0);                             // ease in requires empty animation
                            trackEntry = state.AddAnimation(trackIndex, clipData.animationReference.Animation, clipData.loop, 0);
                        }
                        else
                        {
                            trackEntry = state.SetAnimation(trackIndex, clipData.animationReference.Animation, clipData.loop);
                        }

                        trackEntry.EventThreshold      = clipData.eventThreshold;
                        trackEntry.DrawOrderThreshold  = clipData.drawOrderThreshold;
                        trackEntry.TrackTime           = (float)clipPlayable.GetTime() * (float)clipPlayable.GetSpeed();
                        trackEntry.TimeScale           = (float)clipPlayable.GetSpeed();
                        trackEntry.AttachmentThreshold = clipData.attachmentThreshold;
                        trackEntry.HoldPrevious        = clipData.holdPrevious;

                        if (clipData.customDuration)
                        {
                            trackEntry.MixDuration = customMixDuration;
                        }

                        timelineStartedTrackEntry = trackEntry;
                    }
                    //else Debug.LogWarningFormat("Animation named '{0}' not found", clipData.animationName);
                }

                // Ensure that the first frame ends with an updated mesh.
                if (skeletonAnimation)
                {
                    skeletonAnimation.Update(0);
                    skeletonAnimation.LateUpdate();
                }
                else if (skeletonGraphic)
                {
                    skeletonGraphic.Update(0);
                    skeletonGraphic.LateUpdate();
                }
            }
            startingClips[0] = startingClips[1] = ScriptPlayable <SpineAnimationStateBehaviour> .Null;
            if (lastAnyClipPlaying && !anyClipPlaying)
            {
                HandleClipEnd();
            }
            this.lastAnyClipPlaying = anyClipPlaying;
        }
Exemple #7
0
        public void PreviewEditModePose(Playable playable, SkeletonAnimation spineComponent)
        {
            if (Application.isPlaying)
            {
                return;
            }
            if (spineComponent == null)
            {
                return;
            }

            int inputCount    = playable.GetInputCount();
            int lastOneWeight = -1;

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

            if (lastOneWeight != -1)
            {
                ScriptPlayable <SpineAnimationStateBehaviour> inputPlayableClip = (ScriptPlayable <SpineAnimationStateBehaviour>)playable.GetInput(lastOneWeight);
                SpineAnimationStateBehaviour clipData = inputPlayableClip.GetBehaviour();

                var skeleton = spineComponent.Skeleton;

                bool skeletonDataMismatch = clipData.animationReference != null && spineComponent.SkeletonDataAsset.GetSkeletonData(true) != clipData.animationReference.SkeletonDataAsset.GetSkeletonData(true);
                if (skeletonDataMismatch)
                {
                    Debug.LogWarningFormat("SpineAnimationStateMixerBehaviour tried to apply an animation for the wrong skeleton. Expected {0}. Was {1}", spineComponent.SkeletonDataAsset, clipData.animationReference.SkeletonDataAsset);
                }

                // Getting the from-animation here because it's required to get the mix information from AnimationStateData.
                Animation fromAnimation = null;
                float     fromClipTime  = 0;
                bool      fromClipLoop  = false;
                if (lastOneWeight != 0 && inputCount > 1)
                {
                    var fromClip     = (ScriptPlayable <SpineAnimationStateBehaviour>)playable.GetInput(lastOneWeight - 1);
                    var fromClipData = fromClip.GetBehaviour();
                    fromAnimation = fromClipData.animationReference.Animation;
                    fromClipTime  = (float)fromClip.GetTime();
                    fromClipLoop  = fromClipData.loop;
                }

                Animation toAnimation = clipData.animationReference.Animation;
                float     toClipTime  = (float)inputPlayableClip.GetTime();
                float     mixDuration = clipData.mixDuration;

                if (!clipData.customDuration && fromAnimation != null)
                {
                    mixDuration = spineComponent.AnimationState.Data.GetMix(fromAnimation, toAnimation);
                }

                // Approximate what AnimationState might do at runtime.
                if (fromAnimation != null && mixDuration > 0 && toClipTime < mixDuration)
                {
                    skeleton.SetToSetupPose();
                    float fauxFromAlpha = (1f - toClipTime / mixDuration);
                    fauxFromAlpha = fauxFromAlpha > 0.5f ? 1f : fauxFromAlpha * 2f;                                                     // fake value, but reduce dip.
                    fromAnimation.Apply(skeleton, 0, fromClipTime, fromClipLoop, null, fauxFromAlpha, MixPose.Setup, MixDirection.Out); //fromAnimation.PoseSkeleton(skeleton, fromClipTime, fromClipLoop);
                    toAnimation.Apply(skeleton, 0, toClipTime, clipData.loop, null, toClipTime / mixDuration, MixPose.Current, MixDirection.In);
                }
                else
                {
                    skeleton.SetToSetupPose();
                    toAnimation.PoseSkeleton(skeleton, toClipTime, clipData.loop);
                }
            }
            // Do nothing outside of the first clip and the last clip.
        }
        public void PreviewEditModePose(Playable playable, SkeletonAnimation spineComponent)
        {
            if (Application.isPlaying)
            {
                return;
            }
            if (spineComponent == null)
            {
                return;
            }

            int inputCount    = playable.GetInputCount();
            int lastOneWeight = -1;

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

            if (lastOneWeight != -1)
            {
                ScriptPlayable <SpineAnimationStateBehaviour> inputPlayableClip = (ScriptPlayable <SpineAnimationStateBehaviour>)playable.GetInput(lastOneWeight);
                SpineAnimationStateBehaviour clipData = inputPlayableClip.GetBehaviour();

                var skeleton = spineComponent.Skeleton;

                bool skeletonDataMismatch = clipData.animationReference != null && spineComponent.SkeletonDataAsset.GetSkeletonData(true) != clipData.animationReference.SkeletonDataAsset.GetSkeletonData(true);
                if (skeletonDataMismatch)
                {
                    Debug.LogWarningFormat("SpineAnimationStateMixerBehaviour tried to apply an animation for the wrong skeleton. Expected {0}. Was {1}", spineComponent.SkeletonDataAsset, clipData.animationReference.SkeletonDataAsset);
                }

                // Getting the from-animation here because it's required to get the mix information from AnimationStateData.
                Animation fromAnimation = null;
                float     fromClipTime  = 0;
                bool      fromClipLoop  = false;
                if (lastOneWeight != 0 && inputCount > 1)
                {
                    var fromClip     = (ScriptPlayable <SpineAnimationStateBehaviour>)playable.GetInput(lastOneWeight - 1);
                    var fromClipData = fromClip.GetBehaviour();
                    fromAnimation = fromClipData.animationReference != null ? fromClipData.animationReference.Animation : null;
                    fromClipTime  = (float)fromClip.GetTime();
                    fromClipLoop  = fromClipData.loop;
                }

                Animation toAnimation = clipData.animationReference != null ? clipData.animationReference.Animation : null;
                float     toClipTime  = (float)inputPlayableClip.GetTime();
                float     mixDuration = clipData.mixDuration;

                if (!clipData.customDuration && fromAnimation != null && toAnimation != null)
                {
                    mixDuration = spineComponent.AnimationState.Data.GetMix(fromAnimation, toAnimation);
                }

                // Approximate what AnimationState might do at runtime.
                if (fromAnimation != null && mixDuration > 0 && toClipTime < mixDuration)
                {
                    dummyAnimationState = dummyAnimationState ?? new AnimationState(spineComponent.skeletonDataAsset.GetAnimationStateData());

                    var  toTrack   = dummyAnimationState.GetCurrent(0);
                    var  fromTrack = toTrack != null ? toTrack.mixingFrom : null;
                    bool isAnimationTransitionMatch = (toTrack != null && toTrack.animation == toAnimation && fromTrack != null && fromTrack.animation == fromAnimation);

                    if (!isAnimationTransitionMatch)
                    {
                        dummyAnimationState.ClearTracks();
                        fromTrack = dummyAnimationState.SetAnimation(0, fromAnimation, fromClipLoop);
                        fromTrack.AllowImmediateQueue();
                        if (toAnimation != null)
                        {
                            toTrack = dummyAnimationState.SetAnimation(0, toAnimation, clipData.loop);
                        }
                    }

                    // Update track times.
                    fromTrack.trackTime = fromClipTime;
                    if (toTrack != null)
                    {
                        toTrack.trackTime = toClipTime;
                        toTrack.mixTime   = toClipTime;
                    }

                    // Apply Pose
                    skeleton.SetToSetupPose();
                    dummyAnimationState.Update(0);
                    dummyAnimationState.Apply(skeleton);
                }
                else
                {
                    skeleton.SetToSetupPose();
                    if (toAnimation != null)
                    {
                        toAnimation.PoseSkeleton(skeleton, toClipTime, clipData.loop);
                    }
                }
            }
            // Do nothing outside of the first clip and the last clip.
        }
Exemple #9
0
        // NOTE: This function is called at runtime and edit time. Keep that in mind when setting the values of properties.
        public override void ProcessFrame(Playable playable, FrameData info, object playerData)
        {
            var trackBinding = playerData as SkeletonAnimation;

            if (trackBinding == null)
            {
                return;
            }

            if (!Application.isPlaying)
            {
                                #if SPINE_EDITMODEPOSE
                PreviewEditModePose(playable, trackBinding);
                                #endif
                return;
            }

            int inputCount = playable.GetInputCount();

            if (this.lastInputWeights == null || this.lastInputWeights.Length < inputCount)
            {
                this.lastInputWeights = new float[inputCount];

                for (int i = 0; i < inputCount; i++)
                {
                    this.lastInputWeights[i] = 0f;
                }
            }

            var lastInputWeights = this.lastInputWeights;

            for (int i = 0; i < inputCount; i++)
            {
                float lastInputWeight = lastInputWeights[i];
                float inputWeight     = playable.GetInputWeight(i);
                bool  trackStarted    = inputWeight > lastInputWeight;
                lastInputWeights[i] = inputWeight;

                if (trackStarted)
                {
                    ScriptPlayable <SpineAnimationStateBehaviour> inputPlayable = (ScriptPlayable <SpineAnimationStateBehaviour>)playable.GetInput(i);
                    SpineAnimationStateBehaviour input = inputPlayable.GetBehaviour();
                    Spine.Animation animation          = trackBinding.Skeleton.Data.FindAnimation(input.animationName);

                    if (animation != null)
                    {
                        Spine.TrackEntry trackEntry = trackBinding.AnimationState.SetAnimation(0, input.animationName, input.loop);

                        trackEntry.EventThreshold      = input.eventThreshold;
                        trackEntry.DrawOrderThreshold  = input.drawOrderThreshold;
                        trackEntry.AttachmentThreshold = input.attachmentThreshold;

                        if (input.customDuration)
                        {
                            trackEntry.MixDuration = input.mixDuration;
                        }
                    }
                    else if (string.IsNullOrEmpty(input.animationName))
                    {
                        float mixDuration = input.customDuration ? input.mixDuration : trackBinding.AnimationState.Data.DefaultMix;
                        trackBinding.AnimationState.SetEmptyAnimation(0, mixDuration);
                        continue;
                    }
//					else {
//						Debug.LogWarningFormat("Animation named '{0}' not found", input.animationName);
//					}
                }
            }
        }
Exemple #10
0
        public void PreviewEditModePose(Playable playable, SkeletonAnimation trackBinding)
        {
            if (Application.isPlaying)
            {
                return;
            }
            if (trackBinding == null)
            {
                return;
            }

            int inputCount    = playable.GetInputCount();
            int lastOneWeight = -1;

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

            if (lastOneWeight != -1)
            {
                ScriptPlayable <SpineAnimationStateBehaviour> inputPlayableClip = (ScriptPlayable <SpineAnimationStateBehaviour>)playable.GetInput(lastOneWeight);
                SpineAnimationStateBehaviour clipBehaviourData = inputPlayableClip.GetBehaviour();

                var skeleton     = trackBinding.Skeleton;
                var skeletonData = trackBinding.Skeleton.Data;

                ScriptPlayable <SpineAnimationStateBehaviour> fromClip;
                Animation fromAnimation = null;
                float     fromClipTime  = 0;
                bool      fromClipLoop  = false;
                if (lastOneWeight != 0 && inputCount > 1)
                {
                    fromClip = (ScriptPlayable <SpineAnimationStateBehaviour>)playable.GetInput(lastOneWeight - 1);
                    var fromClipData = fromClip.GetBehaviour();
                    fromAnimation = skeletonData.FindAnimation(fromClipData.animationName);
                    fromClipTime  = (float)fromClip.GetTime();
                    fromClipLoop  = fromClipData.loop;
                }

                Animation toAnimation = skeletonData.FindAnimation(clipBehaviourData.animationName);
                float     toClipTime  = (float)inputPlayableClip.GetTime();
                float     mixDuration = clipBehaviourData.mixDuration;
                if (!clipBehaviourData.customDuration && fromAnimation != null)
                {
                    mixDuration = trackBinding.AnimationState.Data.GetMix(fromAnimation, toAnimation);
                }

                // Approximate what AnimationState might do at runtime.
                if (fromAnimation != null && mixDuration > 0 && toClipTime < mixDuration)
                {
                    skeleton.SetToSetupPose();
                    float fauxFromAlpha = (1f - toClipTime / mixDuration);
                    fauxFromAlpha = fauxFromAlpha > 0.5f ? 1f : fauxFromAlpha * 2f;                                                     // fake value, but reduce dip.
                    fromAnimation.Apply(skeleton, 0, fromClipTime, fromClipLoop, null, fauxFromAlpha, MixPose.Setup, MixDirection.Out); //fromAnimation.PoseSkeleton(skeleton, fromClipTime, fromClipLoop);
                    toAnimation.Apply(skeleton, 0, toClipTime, clipBehaviourData.loop, null, toClipTime / mixDuration, MixPose.Current, MixDirection.In);
                }
                else
                {
                    skeleton.SetToSetupPose();
                    toAnimation.PoseSkeleton(skeleton, toClipTime, clipBehaviourData.loop);
                }
            }
            // Do nothing outside of the first clip and the last clip.
        }