- 수정됨
[cocos2d-x] How to pause a track and resume
Hi,
I am developing a game, when the hero performs a special skill, I want to pause the attack animation of the hero, then play a cool effect, after that I want to resume the attack animation.
I look through the SkeletonAnimation API but cannot find one of that usage.
Can sb. help?
Thanks!
Stop sending updates to the character. Figure out how to pause or scale the updates leading up to the point you want to pause.
If I were writing a game where I stopped the action, I would probably slow down leading up to the stopping point, and then speed out of it. In that case I would use easing curves. There is plenty of easing code out there.
The general technique goes like this: your hero's strike animation is 0.75 seconds long and you want to stop the animation at 0.50 to show your effect and then speed back out. Instead of handing the updates directly to the animation, send them through the easing function and that supplies your updates you send to your animation.
From [0.0 -> 0.5] seconds, I would use an easing equation to slow down the updates. Something like ease_out_quadratic.
For X number of seconds, I would pause the animation.
From [0.5->0.75] I would use ease_in_quad to continue the animation.
The only real hitch there is that most easing functions return the time value and you want the delta. That simply means you need to keep track of the previous easing value (starting at zero) and subtract that from the newest value to get a delta to send to
Generally speaking, you're always using an easing equation to send updates to the animation, it's just that you are using a linear equation. Also, when you pause your animation, that's a constant update function that returns 0.0 for X seconds.
Which means that if you are clever, you should be able to write a queue of easing functions that control your character animations:
[ 0.5 ease_out_quad] [ X return 0][0.25 ease_in_quad] // slowdown / pause animation
[∞ Linear: return updateTick] // normal animation
And if that all sounds too complicated, well, just stop the skeleton Node from getting updates...
jpoag wroteStop sending updates to the character. Figure out how to pause or scale the updates leading up to the point you want to pause.
If I were writing a game where I stopped the action, I would probably slow down leading up to the stopping point, and then speed out of it. In that case I would use easing curves. There is plenty of easing code out there.
The general technique goes like this: your hero's strike animation is 0.75 seconds long and you want to stop the animation at 0.50 to show your effect and then speed back out. Instead of handing the updates directly to the animation, send them through the easing function and that supplies your updates you send to your animation.
From [0.0 -> 0.5] seconds, I would use an easing equation to slow down the updates. Something like ease_out_quadratic.
For X number of seconds, I would pause the animation.
From [0.5->0.75] I would use ease_in_quad to continue the animation.The only real hitch there is that most easing functions return the time value and you want the delta. That simply means you need to keep track of the previous easing value (starting at zero) and subtract that from the newest value to get a delta to send to
Generally speaking, you're always using an easing equation to send updates to the animation, it's just that you are using a linear equation. Also, when you pause your animation, that's a constant update function that returns 0.0 for X seconds.
Which means that if you are clever, you should be able to write a queue of easing functions that control your character animations:
[ 0.5 ease_out_quad] [ X return 0][0.25 ease_in_quad] // slowdown / pause animation
[∞ Linear: return updateTick] // normal animationAnd if that all sounds too complicated, well, just stop the skeleton Node from getting updates...
Thanks jpoag, your information is really helpful!
But if I just want a simple solution, how can I "just stop the skeleton Node from getting updates..."?
Currently I'm calling SkeletonAnimation::addAnimation to run the attack animation, without calling update method directly, can I have the work done through SkeletonAnimation API, or do I need to look into low level spine/cocos2d-x API?
Want you want to do is override the default functionality of the SkeletonRenderer, which is a base class of SkeletonAnimation.
Something like:
class SkatouSpineAnimation : public SkeletonAnimation{
public:
void update (float deltaTime) override {
// custom code
if(!paused) SkeletonAnimation::update(deltaTime);
}
}
Then, instead of spawning SkeletonAnimations, use SkatouSpineAnimation exactly as you would SkeletonAnimation.
jpoag wroteWant you want to do is override the default functionality of the SkeletonRenderer, which is a base class of SkeletonAnimation.
Something like:
class SkatouSpineAnimation : public SkeletonAnimation{ public: void update (float deltaTime) override { // custom code if(!paused) SkeletonAnimation::update(deltaTime); } }
Then, instead of spawning SkeletonAnimations, use SkatouSpineAnimation exactly as you would SkeletonAnimation.
I see! Thanks!
There may be some cocos2d-x way of stopping updates?
Yes, cocos2d-x has a built in way to do this. If you want to pause everything the character is doing you can simply use:
SkeletonAnimation *_character = ...
...
// pause
_character->pause();
// resume
_character->resume();
NOTE: this also pauses any actions being performed on the character. If you want to continue the actions, but just pause the animation, do this instead:
// pause
_scheduler->pauseTarget(_character);
// resume
_scheduler->resumeTarget(_character);
_scheduler is declared in the Node class, so all classes that inherit from it have access to it.
toojuice wroteYes, cocos2d-x has a built in way to do this. If you want to pause everything the character is doing you can simply use:
SkeletonAnimation *_character = ... ... // pause _character->pause(); // resume _character->resume();
NOTE: this also pauses any actions being performed on the character. If you want to continue the actions, but just pause the animation, do this instead:
// pause _scheduler->pauseTarget(_character); // resume _scheduler->resumeTarget(_character);
_scheduler is declared in the Node class, so all classes that inherit from it have access to it.
Thanks toojuice, a cocos2d-x way should be better as it avoid extra update function calls.
jpoag wroteWant you want to do is override the default functionality of the SkeletonRenderer, which is a base class of SkeletonAnimation.
I tried this, but my resulting CustomSkeletonAnimation loses the drop-down menus in the Unity Inspector. E.g. The drop-down menu "Animation" becomes a public string "AnimationName".
I want to accomplish something similar as OP. I just want my character to freeze in the position of the last key frame in a given attack animation until I clear the AnimationState with AnimationState.ClearTracks() or another AnimationState.SetAnimation(). I know I can accomplish this by extending the last key frame over a bunch of frames in the Spine editor, but I want to control this with code which will provide much more flexibility.
Can this be achieved in the current version of stock Spine? Or does anyone know how to do this in Unity?