BinaryCats

Hi

So, we have an animation which interrupts any animation currently being played. Now it has come to a point where I want do replay the animation from different points, depending on when the animation was interrupted.

Will the default blend/mix happen if I start the animation not from the beginning (i.e. settingtime and lasttime to x), if not (which I wouldn't be surprised by) would there be any work arounds?

I understand I could split the animation into different parts and queue them up. I would rather not do this because it would mean, for example, an attack animation would have 8 different animations rather than 1 animation.

-- 08 Mar 2016, 15:53 --

I wish you could pass in a start time with addAnimation :(
Аватара пользователя
BinaryCats
  • Сообщения: 1299

Pharan

I think nothing would stop it from mixing correctly. Spine.AnimationState does mixing according to TrackEntry mix time fields, not the time and lastTime fields.
AddAnimation also still returns the TrackEntry which you can change the start time of, just like SetAnimation.
This is weird for you, BinaryCats. Asking this before actually trying it. :D

If you get to a point where it gets complicated dancing around AnimationState though, you should modify AnimationState.cs in your project to suit your needs.
Аватара пользователя
Pharan
  • Сообщения: 5366

BinaryCats

I had a eureka moment when I thought I could just add a optional parameter to addAnimation for entry.time. I was wrong. I still think it would be possible to queue an animation with a start time of x and for it to mix correctly. but the
TrackEntry next = current.next;
if (next != null) {
next.time = current.lastTime - next.delay;
if (next.time >= 0) SetCurrent(i, next);
is what needs editing, and im unsure how :(


the returned TrackEntry is actually what I need! maybe.. it wont mix, but maybe it will be good enough.

And, sorry other unity developer who worked on this, the integration of spine into our project isn't the best (unlike my integration on our in house engine, oh yeah! :P

Another approach was to grab the current trackentry, and place it after the interrupted animation. As the interrupted animation leaves the animation where it started, no blending would be needed. However this could result in some funny looking animations.

-- 08 Mar 2016, 16:23 --

And I would prefer not to use Spine's API object types.

-- 08 Mar 2016, 16:27 --

BinaryCats писал(а):the returned TrackEntry is actually what I need!
it wasn't what I need. The above code would still need editing so it doesn't get reset when it does it thing

OH WAIT! THE DELAY COULD BE NEGATIVE!... oh, no, nvm, that would play it before the animation :(

-- 08 Mar 2016, 16:37 --

And I cant set the time when the animation starts (after the interrupt). It would be too late then :(. (the milestone object would have been destroyed, and where I would have to do the check wouldn't be a very nice place to look at other components)


note: I have events which I am calling milestones once the animation passes a milestone the anim info will be stored. if the animation gets interrupted it needs to continue from the latest milestone after the interrupt has stopped. the stored (most recent) milestone gets set to null on completion of animations, as to not continue from a mile stone X animations ago
Аватара пользователя
BinaryCats
  • Сообщения: 1299

Pharan

That's an odd block of code: https://github.com/EsotericSoftware/spine-runtimes/blob/master/spine-csharp/src/AnimationState.cs#L85-L87
I guess it tries some kind of sync between next and previous.
I guess if you don't need the syncing and the delaying, you could just rip that thing out. :D
Unity has coroutines anyway.

Did you try subscribing to the TrackEntry's Start event when you call SetAnimation/AddAnimation so you can modify the time when it starts playing?

So mixing with custom start time using AddAnimation didn't work out because of that block of code that modifies its time. Did it work with SetAnimation?

I'm putting this up as an issue on github. :D
Аватара пользователя
Pharan
  • Сообщения: 5366

BinaryCats

Previous block of code is royally bugged. If you have a delay time of longer than the animation, it bugs out. I created a bug report on the forum but it was when nate was on his hiatus.

I haven't. again, our implementation of spine is... yay. I will fiddle with the code for the start event. good idea!

I didn't try set animation, however it isn't particularly needed, because as soon as you say setAnim you can edit the time as it would be the current track. We do this (A LOT) in another game, and we play animations backwards using this method (used in loading bars)

-- 08 Mar 2016, 17:06 --

[C Runtime] Add Animation with Delay Bug is the thread, although code may not be 100%

-- 08 Mar 2016, 17:15 --

TrackEntry next = current.next;
if (next != null) {
float a = current.lastTime - next.time + next.delay;
next.time = current.lastTime - next.delay;
if (next.time >= 0) { next.time = a; next.lastTime = a; SetCurrent(i, next); };
} else {
// End non-looping animation when it reaches its end time and there is no next entry.
if (!current.loop && current.lastTime >= current.endTime) ClearTrack(i);
}
public TrackEntry AddAnimation (int trackIndex, Animation animation, bool loop, float delay, float startTime = 0) {
...
entry.time = startTime;
This code makes it work! kinda
Something isn't quite right, im not sure what. it misses the final key of animations? basically we fade a character in from black, and using the above code the character is darker than usual.

We do something like addfadein queueidle (delay of 0). Seems like the fadein didn't finish playing

-- 08 Mar 2016, 17:55 --

well, there is an arithmetic error. sometimes, kinda. Reson why the fade didn't happen was infact because of the blend. but I did not expect those animations to be skipped forward. code above is incorrect, but on the right track maybe

-- 08 Mar 2016, 18:00 --

TrackEntry next = current.next;
if (next != null) {
float timea = next.time;
float a = current.lastTime - next.delay;
bool b = false;
if (next.time > 0)
{
b = true;
a = current.lastTime - next.time + next.delay;
}
float c;
c = current.lastTime - next.delay;
if (c >= 0) {
if (b)
{
next.time = a; next.lastTime = a;
}
else
next.time = a;
SetCurrent(i, next);
};
} else {
This kinda works. but im unsure if I have broken events.

-- 08 Mar 2016, 18:09 --

events work fine, its just the a = current.lastTime - next.time + next.delay; which is incorrect (again I set the next.time) in the addanimation function
Аватара пользователя
BinaryCats
  • Сообщения: 1299

Xelnath

I feel like I did exactly this thing before...
int iTrack = s.Track;
skeleton.state.SetAnimation(iTrack, s.Animation, (bool) s.Looping);
if (bReset) ResetBones();
skeleton.state.GetCurrent(iTrack).Time = skeleton.state.GetCurrent(iTrack).EndTime * fProgress;
No, nevermind. The above is just a simple animation resume. Doesn't do blending.
Xelnath
  • Сообщения: 408

BinaryCats

[quote="Xelnath"][/quote]See, there is people who want this :)

Again, with Xelnath code, this is setting the animation, and I want to do it through addanimation. although both are valid use cases

-- 09 Mar 2016, 09:37 --

a = (next.time + current.lastTime) - next.delay;
fresh eyes tells me this is the solution. blending doesn't seam to work though
Аватара пользователя
BinaryCats
  • Сообщения: 1299


Вернуться в Unity