[Gold] How to control animation with multiple meshes sharing a single AnimationSet

Software: Away3D 4.x

Avatar
Matse, Sr. Member
Posted: 19 July 2012 12:31 PM   Total Posts: 149

I guess I must be missing/overlooking something obvious but I can’t seem to figure out how we are supposed to control animations of several cloned meshes sharing the same AnimationSet (and so the same AnimationStates).

I’m working on a diablo-like game project, in any game level I have many monsters of the same type : skeleton warriors, ghosts etc
Each of these monsters does his own stuff : wandering, attacking, staying idle, getting hit, dying…

My question is pretty simple : what’s the recomended way to detect that monster n° 57 just finished his attack move ?
This *cannot* be done by adding an EventListener to the attack move’s AnimationState : all monsters of the same type are using the same ones. If I add eventListeners on AnimationStates, it’ll only let me know that some monster amongst the dozen of monsters of the same type, just finished playing the attack animation.

To me the logical way would be to add an EventListener on the monsters meshes Animators, since every monster has its own. But that’s not how it works right now.

About 10 months ago I made this post on the subject : http://away3d.com/forum/viewthread/827/
Here is the Github issue https://github.com/away3d/away3d-core-fp11/issues/118

Rob closed it, stating that the Animator should only dispatch a STOP event when the Animator’s stop() method is called.
I’m not sure how useful it is to get a STOP event only when explicitly calling stop(), I guess there are use cases I didn’t think of, but I still think we need an event letting us know that an Animator just finished playing an animation.

Prior to Gold version I was using animations durations : every monster had an animationEndTime when playing a non-looping animation. With Gold version it doesn’t seem very easy to get an Animation’s duration, which led me to raise this question.

   

Richard Olsson, Administrator
Posted: 19 July 2012 01:31 PM   Total Posts: 1192   [ # 1 ]

I see your problem. Please file a feature request for ANIMATION_END events.

As far as the duration goes, that is a property that will very soon be available. It’s currently private, but you could create your own temporary public getter on the node classes, and get it through mesh.animator.activeState.rootJoint. It should be added in the dev branch soon though.

   

Avatar
Matse, Sr. Member
Posted: 19 July 2012 01:53 PM   Total Posts: 149   [ # 2 ]

Thanks for the quick answer Richard, should I create a new thread in the forum’s “feature request” section, or an “issue” or Github ?

Agreed on adding a getter for duration, for now I’m trying to understand and isolate a weird issue that I have with at least one animation (imported from MD5) where for some reason it seems to play backwards, and generates an error trying to play a frame with a ridiculously high index that is, of course, out of range.
I’ll probably create another thread on that one once I get my head around it smile

   

Shegl, Sr. Member
Posted: 19 July 2012 03:00 PM   Total Posts: 134   [ # 3 ]

I dont see your problem in my way ^_^.

I’m working on Ultima Online kind of the game with same needs.

And using:

animator = new SkeletonAnimatormain_root.models.models_array[bodyid].anim_set, (main_root.models.models_array[bodyid].skeleton as Skeleton)); 

Then just apply to mesh:

animator.addEventListener(AnimatorEvent.STOPonSequenceDone);
usedMesh.animator animator

so My Mesh is in Objectcontainer3d extended class with own animation controls.

I use same skeleton and animation for all my meshes and doesnt see any problems..

Mb I just dont understand your request for feature?

   

Avatar
Matse, Sr. Member
Posted: 19 July 2012 03:25 PM   Total Posts: 149   [ # 4 ]

Hi Shegl,

The problem is definetely not using the same skeleton and animationSet : that’s what I do, and what I did before gold already : works great. My engine is pretty advanced already : player and monsters can move, fight etc

The problem is not having skeleton warrior n°38 playing an idle animation while skeleton warrior n°82 plays an attack one, for example.

The problem is to have a way to get a notification when skeleton warrior n°82 attack animation ends.

I don’t know about you, but for me this :

animator.addEventListener(AnimatorEvent.STOPonSequenceDone); 

is totally useless right now, as the animator will never fire an AnimatorEvent.STOP event, unless I call animator.stop(). That’s not a problem that’s specific to my models or animation since :

1. Rob stated explicitly on the github issue I linked to that it was meant to work this way.

2. I can reproduce this with the Intermediate_MD5Animation example, if I comment out the part where it adds EventListeners on AnimationStates and add

animator.addEventListener(AnimatorEvent.STARTonPlaybackStart);
animator.addEventListener(AnimatorEvent.STOPonPlaybackComplete); 

(of course I also set the event parameter type in those callback functions to AnimatorEvent).

If you do this then try any of the non-looping animations you’ll see the monster stop at the end of the sequence, while never receiving a STOP event. Also you will only get the START event once.

Otherwise I agree, that’s exactly how it should work in my opinion smile

Let me know if it works differently in your experience, I’m always happy to share and learn !

   

Avatar
Matse, Sr. Member
Posted: 19 July 2012 04:52 PM   Total Posts: 149   [ # 5 ]

Feature request added on github : https://github.com/away3d/away3d-core-fp11/issues/357

   

Shegl, Sr. Member
Posted: 19 July 2012 05:42 PM   Total Posts: 134   [ # 6 ]

May be im just totaly miss understood but you can just:

Add in SkeletonClipNode:

public function clone():SkeletonClipNode {
   
var SkeletonClipN:SkeletonClipNode = new SkeletonClipNode();
   var 
durt:uint 0;
    for 
each(var un:uint in _durations{
     durt 
+= un;
    
}
    durt 
Math.round(durt _durations.length);
   for 
each(var sf:SkeletonPose in _frames{
    SkeletonClipN
.addFrame(sfdurt);
   
}
   
return SkeletonClipN;
  

add in skeletonAnimationState:

public function clone():SkeletonAnimationState {
   
var SAS:SkeletonAnimationState = new SkeletonAnimationState((rootNode as ISkeletonAnimationNode).clone());
   
SAS._stateName stateName;
   
SAS.looping looping;
   return 
SAS;
  

in SkeletonAnimator after:

if (!_activeState)
    throw new 
Error("Animation state " stateName " not found!"); 

add this lines:

_activeState = ((_skeletonAnimationSet.getState(stateName)) as SkeletonAnimationState).clone();
   (
_activeState as SkeletonAnimationState).addEventListener(AnimationStateEvent.PLAYBACK_COMPLETEplayBackComplete); 

playBackComplete code:

private function playBackComplete(e:AnimationStateEvent):void {
   this
.dispatchEvent( new AnimationStateEventAnimationStateEvent.PLAYBACK_COMPLETEe.animationStatee.animationNode));
  

and then just apply event listener to animator:

animator.addEventListener(AnimationStateEvent.PLAYBACK_COMPLETEonSequenceDone); 

^_^ np.

   

Avatar
Matse, Sr. Member
Posted: 19 July 2012 06:17 PM   Total Posts: 149   [ # 7 ]

I have a hard time understanding you Shegl ^^

Thanks for offering a possible solution, but what you propose here is a bit weird as instead of cloning everything all the time in order to use AnimationStateEvent.PLAYBACK_COMPLETE (that’s what you’re doing here basically, through the Animator which then dispatches its event) I’m probably better off cloning the AnimationStates in the first place, create an AnimationSet per mesh and add PLAYBACK_COMPLETE listeners directly on the AnimationStates. Probably a bit better performance-wise even if that means cloned AnimationSets.

But in any case that’s really not optimal : lots of duplicate data, lots of listeners… and quite a few modifications to code pieces that will be replaced the next time I download a new version from dev branch on github smile

I much prefer what Richard suggested : just adding a getter to easily retrieve animation duration and keep monitoring my monsters animationEndTime like I did so far.
I hope the away3D team can come up with a clean and optimal way to get an AnimatorEvent.ANIMATION_END working smile

In your first post you seemed to say you were using the Animator.STOP event, so I guess you have it working only with the code modifications from your second post ?

   

Shegl, Sr. Member
Posted: 19 July 2012 06:48 PM   Total Posts: 134   [ # 8 ]

Matse for me.. Only edited code work for me.

Cause I get the bug when i use in this flow:
I use same AnimationSet and Skeleton for every object.
And then the Obj N1 play Idle animation and the second one Object what play this animation too, clone point to point any deformation.
And it’s very ugly and stupid. I dunno mb this bug fixed already in master brunch, but I cant get it in this time. So if it fixed u can just clone AnimationStates or play with constructor of SkeletonAnimator function and clone all states only on creation of animator..

Just wondering if you had build engine-“is pretty advanced already” why u cant handle it’s simple feature for yourself.

   

Avatar
Matse, Sr. Member
Posted: 19 July 2012 07:38 PM   Total Posts: 149   [ # 9 ]

And then the Obj N1 play Idle animation and the second one Object what play this animation too, clone point to point any deformation.

Ah I see, we had this problem with one of the monsters but since the other ones were fine we assumed it was a problem with the mesh so my graphic artist worked on it and in the end it worked. Not sure what he changed though… should have kept a note about it

Just wondering if you had build engine-“is pretty advanced already” why u cant handle it’s simple feature for yourself.

Oh I can, as I said the animation duration is enough for me. But I’d rather not have to put my own modifications in away3D as I think the away3D team is much better than me at modifying their engine, and don’t like the idea of having to copy/paste all my modifications everytime I get the latest version of away3D, which is quite often.

Also I thought that maybe I was doing things wrong, and there was a working way already that I could have missed.

   

Shegl, Sr. Member
Posted: 19 July 2012 07:49 PM   Total Posts: 134   [ # 10 ]

I got your point.. Btw “Not sure what he changed though… should have kept a note about it” test it, i think it’s still there.

In my online game are already playing beta players.. and they report me a lot of bugs when I switch to Gold release.. so I need fix them faster then the away3d fix and upload to github.=)

   

Avatar
Matse, Sr. Member
Posted: 19 July 2012 08:08 PM   Total Posts: 149   [ # 11 ]

Btw “Not sure what he changed though… should have kept a note about it” test it, i think it’s still there

No it’s not : we fixed the model, the 3D file. That’s the part I should have kept a note about.

As I said I currently have lots of models playing different animations while sharing the exact same AnimationSet, this works (and it worked already with away3d beta). You could probably fix your files too, if only I remembered what we changed to make it work (again, we didn’t have to modify away3d)...

   

Shegl, Sr. Member
Posted: 19 July 2012 08:38 PM   Total Posts: 134   [ # 12 ]

I about “playing different animations while sharing the exact same AnimationSet” not different.. The Same one.

   

neil, Newbie
Posted: 01 March 2013 09:01 AM   Total Posts: 1   [ # 13 ]

Hi! Matse! I have the same problem too . how did you solve it ?

   
   

X

Away3D Forum

Member Login

Username

Password

Remember_me



X