From f67a5457a0ed9e7b9d51d1c76ecdfb9d962e3d35 Mon Sep 17 00:00:00 2001 From: John Date: Thu, 24 Dec 2015 06:53:59 +0800 Subject: [PATCH] Opt-in Generic Autoreset for SkeletonAnimation This allows users to easily let the SkeletonAnimation act like Spine editor (not inheriting poses from previous animations) without adding extra code. --- .../Assets/spine-unity/SkeletonAnimation.cs | 62 ++++++++++++++++--- 1 file changed, 52 insertions(+), 10 deletions(-) diff --git a/spine-unity/Assets/spine-unity/SkeletonAnimation.cs b/spine-unity/Assets/spine-unity/SkeletonAnimation.cs index 7277ce233..d85c569d5 100644 --- a/spine-unity/Assets/spine-unity/SkeletonAnimation.cs +++ b/spine-unity/Assets/spine-unity/SkeletonAnimation.cs @@ -30,7 +30,6 @@ *****************************************************************************/ using System; -using System.IO; using System.Collections.Generic; using UnityEngine; using Spine; @@ -38,12 +37,12 @@ using Spine; [ExecuteInEditMode] [AddComponentMenu("Spine/SkeletonAnimation")] public class SkeletonAnimation : SkeletonRenderer, ISkeletonAnimation { - public float timeScale = 1; - public bool loop; + + /// + /// This is the Spine.AnimationState object of this SkeletonAnimation. You can control animations through it. + /// Note that this object, like .skeleton, is not guaranteed to exist in Awake. Do all accesses and caching to it in Start public Spine.AnimationState state; - - public event UpdateBonesDelegate UpdateLocal { add { _UpdateLocal += value; } remove { _UpdateLocal -= value; } @@ -63,15 +62,13 @@ public class SkeletonAnimation : SkeletonRenderer, ISkeletonAnimation { protected event UpdateBonesDelegate _UpdateWorld; protected event UpdateBonesDelegate _UpdateComplete; + // TODO: Make this a safe getter. Lazy-initialize and avoid double-initialization. public Skeleton Skeleton { - get { - return this.skeleton; - } + get { return this.skeleton; } } [SerializeField] - private String - _animationName; + private String _animationName; public String AnimationName { get { @@ -89,17 +86,62 @@ public class SkeletonAnimation : SkeletonRenderer, ISkeletonAnimation { } } + /// Whether or not an animation should loop. This only applies to the initial animation specified in the inspector, or any subsequent Animations played through .AnimationName. Animations set through state.SetAnimation are unaffected. + #if UNITY_5 + [Tooltip("Whether or not an animation should loop. This only applies to the initial animation specified in the inspector, or any subsequent Animations played through .AnimationName. Animations set through state.SetAnimation are unaffected.")] + #endif + public bool loop; + + /// + /// The rate at which animations progress over time. 1 means 100%. 0.5 means 50%. + /// AnimationState and TrackEntry also have their own timeScale. These are combined multiplicatively. + #if UNITY_5 + [Tooltip("The rate at which animations progress over time. 1 means 100%. 0.5 means 50%.")] + #endif + public float timeScale = 1; + + #if UNITY_5 + [Tooltip("Setting this to true makes the SkeletonAnimation behave similar to Spine editor. New animations will not inherit the pose from a previous animation. If you need to intermittently and programmatically pose your skeleton, leave this false.")] + #endif + [SerializeField] + protected bool autoReset = false; + + /// + /// Setting this to true makes the SkeletonAnimation behave similar to Spine editor. + /// New animations will not inherit the pose from a previous animation. + /// If you need to intermittently and programmatically pose your skeleton, leave this false. + public bool AutoReset { + get { return this.autoReset; } + set { + if (!autoReset && value) { + state.Start -= HandleNewAnimationAutoreset; // make sure there isn't a double-subscription. + state.Start += HandleNewAnimationAutoreset; + } + autoReset = value; + } + } + public override void Reset () { base.Reset(); if (!valid) return; state = new Spine.AnimationState(skeletonDataAsset.GetAnimationStateData()); + + if (autoReset) { + state.Start += HandleNewAnimationAutoreset; + } + if (_animationName != null && _animationName.Length > 0) { state.SetAnimation(0, _animationName, loop); Update(0); } } + + protected virtual void HandleNewAnimationAutoreset (Spine.AnimationState state, int trackIndex) { + if (!autoReset) return; + if (skeleton != null) skeleton.SetToSetupPose(); + } public virtual void Update () { Update(Time.deltaTime);