diff --git a/CHANGELOG.md b/CHANGELOG.md index fc850cb37..b175b2266 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -171,6 +171,10 @@ * **Restrictions** As all Spine shaders, the LWRP shaders **do not support `Premultiply alpha` (PMA) atlas textures in Linear color space**. Please export your atlas textures as `straight alpha` textures with disabled `Premultiply alpha` setting when using Linear color space. You can check the current color space via `Project Settings - Player - Other Settings - Color Space.`. * **Example:** You can find an example scene in the package under `com.esotericsoftware.spine.lwrp-shaders-3.8/Examples/LWRP Shaders.unity` that demonstrates usage of the LWRP shaders. * Added `Spine/Skeleton Lit ZWrite` shader. This variant of the `Spine/Skeleton Lit` shader writes to the depth buffer with configurable depth alpha threshold. Apart from that it is identical to `Spine/Skeleton Lit`. + * Additional yield instructions to wait for animation track events `End`, `Complete` and `Interrupt`. + * `WaitForSpineAnimationComplete` now proves an additional `bool includeEndEvent` parameter, defaults to `false` (previous behaviour). + * Added a new `WaitForSpineAnimationEnd` yield instruction. + * Added a new generic `WaitForSpineAnimation` yield instruction which can be configured to wait for any combination of animation track events. It is now used as base class for `WaitForSpineAnimationComplete` and `WaitForSpineAnimationEnd`. * **Changes of default values** * `SkeletonMecanim`'s `Layer Mix Mode` now defaults to `MixMode.SpineStyle` instead of `MixMode.MixAlways`. diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimation.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimation.cs new file mode 100644 index 000000000..47546e9ec --- /dev/null +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimation.cs @@ -0,0 +1,108 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated May 1, 2019. Replaces all prior versions. + * + * Copyright (c) 2013-2019, Esoteric Software LLC + * + * Integration of the Spine Runtimes into software or otherwise creating + * derivative works of the Spine Runtimes is permitted under the terms and + * conditions of Section 2 of the Spine Editor License Agreement: + * http://esotericsoftware.com/spine-editor-license + * + * Otherwise, it is permitted to integrate the Spine Runtimes into software + * or otherwise create derivative works of the Spine Runtimes (collectively, + * "Products"), provided that each user of the Products must obtain their own + * Spine Editor license and redistribution of the Products in any form must + * include this license and copyright notice. + * + * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS + * INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +using UnityEngine; +using System.Collections; +using System; + +namespace Spine.Unity { + /// + /// Use this as a condition-blocking yield instruction for Unity Coroutines. + /// The routine will pause until the AnimationState.TrackEntry fires any of the + /// configured events. + ///

+ /// See the Spine Unity Events documentation page + /// and + /// for more information on when track events will be triggered.

+ public class WaitForSpineAnimation : IEnumerator { + + [Flags] + public enum AnimationEventTypes + { + Start = 1, + Interrupt = 2, + End = 4, + Dispose = 8, + Complete = 16 + } + + bool m_WasFired = false; + + public WaitForSpineAnimation (Spine.TrackEntry trackEntry, AnimationEventTypes eventsToWaitFor) { + SafeSubscribe(trackEntry, eventsToWaitFor); + } + + #region Reuse + /// + /// One optimization high-frequency YieldInstruction returns is to cache instances to minimize GC pressure. + /// Use NowWaitFor to reuse the same instance of WaitForSpineAnimationComplete. + public WaitForSpineAnimation NowWaitFor (Spine.TrackEntry trackEntry, AnimationEventTypes eventsToWaitFor) { + SafeSubscribe(trackEntry, eventsToWaitFor); + return this; + } + #endregion + + #region IEnumerator + bool IEnumerator.MoveNext () { + if (m_WasFired) { + ((IEnumerator)this).Reset(); // auto-reset for YieldInstruction reuse + return false; + } + + return true; + } + void IEnumerator.Reset () { m_WasFired = false; } + object IEnumerator.Current { get { return null; } } + #endregion + + protected void SafeSubscribe (Spine.TrackEntry trackEntry, AnimationEventTypes eventsToWaitFor) { + if (trackEntry == null) { + // Break immediately if trackEntry is null. + Debug.LogWarning("TrackEntry was null. Coroutine will continue immediately."); + m_WasFired = true; + } + else { + if ((eventsToWaitFor & AnimationEventTypes.Start) != 0) + trackEntry.Start += HandleComplete; + if ((eventsToWaitFor & AnimationEventTypes.Interrupt) != 0) + trackEntry.Interrupt += HandleComplete; + if ((eventsToWaitFor & AnimationEventTypes.End) != 0) + trackEntry.End += HandleComplete; + if ((eventsToWaitFor & AnimationEventTypes.Dispose) != 0) + trackEntry.Dispose += HandleComplete; + if ((eventsToWaitFor & AnimationEventTypes.Complete) != 0) + trackEntry.Complete += HandleComplete; + } + } + + void HandleComplete (TrackEntry trackEntry) { + m_WasFired = true; + } + } +} diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimation.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimation.cs.meta new file mode 100644 index 000000000..ac946e63f --- /dev/null +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimation.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d9be5adcaf0003849a1d181173c19635 +timeCreated: 1566289729 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimationComplete.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimationComplete.cs index 8f15a2f7e..149569c59 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimationComplete.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimationComplete.cs @@ -34,52 +34,29 @@ using Spine; namespace Spine.Unity { /// /// Use this as a condition-blocking yield instruction for Unity Coroutines. - /// The routine will pause until the AnimationState.TrackEntry fires its Complete event. - public class WaitForSpineAnimationComplete : IEnumerator { + /// The routine will pause until the AnimationState.TrackEntry fires its Complete event. + /// It can be configured to trigger on the End event as well to cover interruption. + ///

+ /// See the Spine Unity Events documentation page + /// and + /// for more information on when track events will be triggered. + public class WaitForSpineAnimationComplete : WaitForSpineAnimation, IEnumerator { - bool m_WasFired = false; - - public WaitForSpineAnimationComplete (Spine.TrackEntry trackEntry) { - SafeSubscribe(trackEntry); - } - - void HandleComplete (TrackEntry trackEntry) { - m_WasFired = true; - } - - void SafeSubscribe (Spine.TrackEntry trackEntry) { - if (trackEntry == null) { - // Break immediately if trackEntry is null. - Debug.LogWarning("TrackEntry was null. Coroutine will continue immediately."); - m_WasFired = true; - } else { - trackEntry.Complete += HandleComplete; - } + public WaitForSpineAnimationComplete (Spine.TrackEntry trackEntry, bool includeEndEvent = false) : + base(trackEntry, + includeEndEvent ? (AnimationEventTypes.Complete | AnimationEventTypes.End) : AnimationEventTypes.Complete) + { } #region Reuse ///

/// One optimization high-frequency YieldInstruction returns is to cache instances to minimize GC pressure. /// Use NowWaitFor to reuse the same instance of WaitForSpineAnimationComplete. - public WaitForSpineAnimationComplete NowWaitFor (Spine.TrackEntry trackEntry) { - SafeSubscribe(trackEntry); + public WaitForSpineAnimationComplete NowWaitFor (Spine.TrackEntry trackEntry, bool includeEndEvent = false) { + SafeSubscribe(trackEntry, + includeEndEvent ? (AnimationEventTypes.Complete | AnimationEventTypes.End) : AnimationEventTypes.Complete); return this; } #endregion - - #region IEnumerator - bool IEnumerator.MoveNext () { - if (m_WasFired) { - ((IEnumerator)this).Reset(); // auto-reset for YieldInstruction reuse - return false; - } - - return true; - } - void IEnumerator.Reset () { m_WasFired = false; } - object IEnumerator.Current { get { return null; } } - #endregion - } - } diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimationEnd.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimationEnd.cs new file mode 100644 index 000000000..146a22c14 --- /dev/null +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimationEnd.cs @@ -0,0 +1,59 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated May 1, 2019. Replaces all prior versions. + * + * Copyright (c) 2013-2019, Esoteric Software LLC + * + * Integration of the Spine Runtimes into software or otherwise creating + * derivative works of the Spine Runtimes is permitted under the terms and + * conditions of Section 2 of the Spine Editor License Agreement: + * http://esotericsoftware.com/spine-editor-license + * + * Otherwise, it is permitted to integrate the Spine Runtimes into software + * or otherwise create derivative works of the Spine Runtimes (collectively, + * "Products"), provided that each user of the Products must obtain their own + * Spine Editor license and redistribution of the Products in any form must + * include this license and copyright notice. + * + * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS + * INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +using UnityEngine; +using System.Collections; +using Spine; + +namespace Spine.Unity { + /// + /// Use this as a condition-blocking yield instruction for Unity Coroutines. + /// The routine will pause until the AnimationState.TrackEntry fires its End event. + ///

+ /// See the Spine Unity Events documentation page + /// and + /// for more information on when track events will be triggered.

+ public class WaitForSpineAnimationEnd : WaitForSpineAnimation, IEnumerator { + + public WaitForSpineAnimationEnd (Spine.TrackEntry trackEntry) : + base(trackEntry, AnimationEventTypes.End) + { + } + + #region Reuse + /// + /// One optimization high-frequency YieldInstruction returns is to cache instances to minimize GC pressure. + /// Use NowWaitFor to reuse the same instance of WaitForSpineAnimationComplete. + public WaitForSpineAnimationEnd NowWaitFor (Spine.TrackEntry trackEntry) { + SafeSubscribe(trackEntry, AnimationEventTypes.End); + return this; + } + #endregion + } +} diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimationEnd.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimationEnd.cs.meta new file mode 100644 index 000000000..472b1f96a --- /dev/null +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/YieldInstructions/WaitForSpineAnimationEnd.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 3c5a5fe930d1ab24da154d76b24c2747 +timeCreated: 1566288961 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: