- Modifié
Spine-Unity YieldInstructions
The yield instructions are now part of the latest spine-unity.unitypackage
.
WaitForSpineEvent
yield return new WaitForSpineEvent(skeletonAnimation.state, "spawn bullet");
WaitForSpineAnimationComplete
var track = skeletonAnimation.state.SetAnimation(0, "talk", false);
yield return new WaitForSpineAnimationComplete(track);
They use the IEnumerator interface and not the CustomYieldInstruction class from 5.3.
Despite this, there were changes in Unity's Coroutine system in 5.3 that makes this not work in 5.2 and below, so this does require Unity 5.3 and above.
Very nice feature for the runtime Pharan
Beta 0.15.1230
Try it out! Report bugs in this thread.
WaitForSpineEvent and WaitForSpineAnimationComplete are for use in Unity Coroutines. Learn more about Unity Corutines here:
https://unity3d.com/learn/tutorials/modules/intermediate/scripting/coroutines
http://docs.unity3d.com/Manual/Coroutines.html
Use WaitForSpineEvent
to pause execution of a coroutine until a Spine.AnimationState fires a certain event.
Use WaitForSpineAnimationComplete
to pause execution of a coroutine until an animation played by SetAnimation or AddAnimation completes.
If you're an experienced user, the NowWaitFor
methods allow you to reuse the same instance with new parameters.
Keep in mind that regular yield instructions (yield return null or yield return new WaitForSeconds) in Unity coroutines are updated after Update
(where Spine AnimationState is updated) but before LateUpdate
(where SkeletonRenderer builds the mesh).
The yield instructions are now part of the latest spine-unity.unitypackage
.
hi, Pharan,
i've got some spine animation
it contains animation "shoot" with event "shoot" in 1.5 seconds
i call this code in coroutine:
//...
SkeletonAnimation skeletonAnimation = unit.GetComponent<SkeletonAnimation>();
skeletonAnimation.AnimationName = animationName;
yield return new Spine.WaitForSpineEvent(skeletonAnimation, "shoot", true);
print("shoot event!");
and the message "shoot event!" traced immediatelly
but if i change "yield return new Spine.WaitForSpineEvent(..)" to "yield return new WaitForSeconds(1.5)"
it works with a delay
is it a bug or i doing something wrong?
thanks
Hey Jakob.
One case where it exhibits this behavior is if the SkeletonAnimation is invalid/uninitialized. In that case, the Spine.AnimationState that does the actual firing of the event doesn't exist yet so there's nothing for it to wait for.
https://github.com/EsotericSoftware/spine-runtimes/blob/master/spine-unity/Assets/spine-unity/Modules/YieldInstructions/WaitForSpineEvent.cs#L63-L64
I guess this is an ambiguous case to handle. I should probably make it fail loudly so the user knows what's happening.
I'm not sure if this is your case though. When are you starting your coroutine particularly? Is it in Awake?
thank you for reply Pharan,
unfortunately this is not my case
i starting my coroutine from Update() method, when i click on the enemy to shoot in my game,
animation "idle" is looped playing before
i tried to debug it as you advised, look at image 1:
SubscribeByName called at yield return new Spine.WaitForSpineEvent(..) (after step over on screenhot); after this function called the message "shoot event!" appears in log immediatelly
image 2:
HandleAnimationStateEventByName invoked when needed with values on screenshot (m_WasFired will set to true in next step)
there is exported animation in attachment just in case
i can attach original spine file if needed or make a demo unity-project in which you can debug it
Pharan a écritI should probably make it fail loudly so the user knows what's happening.
that's will very helpful i think
I think nothing's wrong with it. Can you show the coroutine and the code that's starting it instead?
I made a test project named Coroutine
It contains skeleton animation of character and script attached to skeleton animation.
I slowed down time scale to 0.05 so we can see that event emitts emmidiatelly. And i added WaitForSeconds with duration event must to be emitted. This performance starts on left mouse button clicked first time.
Here is the script:
void Start () {
}
void Update () {
if (Input.GetMouseButtonUp(0))
{
SkeletonAnimation sleketonAnimation = GetComponent<SkeletonAnimation>();
if (sleketonAnimation.AnimationName != "shoot")
{
sleketonAnimation.AnimationName = "shoot";
StartCoroutine(shootCoroutine());
}
}
}
IEnumerator shootCoroutine()
{
SkeletonAnimation sleketonAnimation = GetComponent<SkeletonAnimation>();
yield return new Spine.WaitForSpineEvent(sleketonAnimation, "shoot");
print("shoot event!");
yield return new WaitForSeconds(0.166f/sleketonAnimation.timeScale);
print("delayed event!");
yield break;
}
Here full project, that can be opened in Unity and launched.
https://www.dropbox.com/s/5v16zq8orzewrvy/Coroutine.zip?dl=0
I opened the project in Unity.
It works correctly. The "shoot" event gets logged when the knife disappears.
Can I get anyone else to confirm?
Also, next time when you're sharing your project, you don't need to include the Library folder. That's mostly large files that Unity can regenerate by itself.
I don't think it matters, but are you using Unity 4.x?
Pharan a écritI opened the project in Unity.
It works correctly. The "shoot" event gets logged when the knife disappears.
It's so strange. Please, watch the video by link
https://www.dropbox.com/s/pr4f7l4mpv24vqt/bandicam%202016-02-21%2014-06-02-793.avi?dl=0
"shoot event" traced at mouse down, but "delayed event" traced when the knife disappears.
Pharan a écritAlso, next time when you're sharing your project, you don't need to include the Library folder. That's mostly large files that Unity can regenerate by itself.
Ok, thanks, now i know
Pharan a écritI don't think it matters, but are you using Unity 4.x?
I've got Unity 5.2.2f1 Personal
Have you tried deleting your Library folder? (make a backup, of course)
I have closed Unity now then removed Library folder and reopen project and nothing were changed.
Ok thank you Pharan. I will open and build it on another computer and share this experience tomorrow
22 фев 2016, 13:03
I built this project on another computer and it works correctly.
Differences:
Unity 5.2.2f1 — Unity 5.3.2f1
Windows 7 — Windows 10
Does anyone have any ideas what test I can organize to expose the real reason of this bug?
Are you saying even the Coroutine project you shared didn't work properly in your 5.2.2/Win7 setup?
Yes exactly.
Now I prepared binary build (exe-file with data folder) which works fine on Win10 and I am going to execute it on Win7 where it did not work properly.
I think it's not working in 5.2. (contrary to what I've read in the Unity forums)
Hi Pharan,
You were right. I have launch program that built in Unity 5.3.2 on my Win7 computer and it works fine. I updated Unity to 5.3.2 and run it and it works fine too.
Now we know: WaitForSpineEvent and WaitForSpineAnimationComplete can be used since Unity 5.3.2
Thanks to all
This is a good find (even if it's disappointing).
I'll add a Debug.LogWarning to the constructor if the user isn't using 5.3 and up so they know it's not compatible with older versions.
noice ty
I suspected there'd be problems if bcats replies to an old topic.
But I'm glad it just came in handy. XD
Did you use it?
Pharan a écritI suspected there'd be problems if bcats replies to an old topic.
But I'm glad it just came in handy. XD
Did you use it?
yeah previously we where effectively string comparing every frame to wait for an animation to stop
while( currentanim == "anim")
yield return null
I never got around testing out this stuff