Loading character with animations to scene and cloning it with animation groups

Hi everyone! I have a similar pickle that the person in this thread: How the heck do you load in your model with animations?

I’m trying to develop a large-ish game with Babylon.js. Currently I have some static models (wall pieces, floor pieces, general assets and objects that are in the map) and now some characters with animations. I currently use the AssetsManager to load all the required stuff, with bit of a different handling on the success -method with static assets and characters.

What I try to do with characters is the following:

  1. Load the character glb file with AssetsManager
  2. Save the result for easy access and future use on my own plain JavaScript object
  3. When needed, fetch the character model and animations and play one of the many animations
  4. Change the animation if needed (running to walk, inspired by https://playground.babylonjs.com/#6I67BL#2)

This requires me to clone the mesh and animations somehow. The animations per clone need to be individual as well. In the other thread there was this solution: https://playground.babylonjs.com/#AJA5J6#76
However, I would prefer to use AssetsManager and store the models/animations to a storage I can kind of take care of my own, if possible. Other reason to use AssetsManager is that the loader for all asset types is the same one.

So the question is can I use the AssetsManager to load somewhat complex characters and clone them with animations somehow? I’ve been trying to figure this out with my own model for hours now, feeling a bit desperate… The model I am currently using is working in sandbox perfectly with multiple animations and it also loads into the scene well (if setEnabled(true)). The only problem is the actual instantiation of the characters to the scene with the animations.

1 Like

Shortly, instances will always play the same animation group; clones are able to play different animation groups.
As for your Assets Manager question, these threads may be helpful
Cloning with AssetsManager
meshTask + clone + animationGroups
PG Example - https://playground.babylonjs.com/#ZQPDEF#18

1 Like

Yeah, it is the cloning I want to achieve! :slight_smile:

The playground example with the planes is kind of what I am looking for, but it still feels a bit “hacky” way to achieve the end goal. It uses the asset container and extends the AbstractAssetTask… I would like to use one or another :slight_smile:

So I made two tests. The first one is with asset containers. Seems to work pretty well, attached it to this playground with my custom model that I am using in my game: https://playground.babylonjs.com/#S7E00P#39

However, I would like to know a bit deeper how everything works and what goes into cloning mesh/animation/skeleton data. I also would still, stubbornly, prefer to use assetManager. I have created a playground for this purpose, but I don’t really understand what magic I am missing:
I try to clone the root mesh, then the skeleton and animationgroups. When I do this I think I can’t bind the skeleton to the new mesh properly as the scaling seems really of as you can see from the next picture :laughing: … I am also using Mixamo animations, so I wonder if they do something naughty to the model itself? :thinking:

You need to assign the cloned skeleton to the cloned mesh : https://playground.babylonjs.com/#S7E00P#44

1 Like

Thank you @sebavan ! Looks really good now!

Then, the only thing left is to understand how the animation group cloning works. Currently the animation groups, even though cloned, are somehow linked to the original skeleton/mesh? In the asset container code, the cloning process tries to attach the animation groups to the clone skeleton/mesh, right? Here are the actual lines for it: Babylon.js/assetContainer.ts at master · BabylonJS/Babylon.js · GitHub

So I should pretty much try to have the new cloned skeleton bones saved somewhere and try to attach the cloned animation group TargetedAnimations to it?

1 Like

Yup I would think so.

1 Like

Tried to do this the similar way asset containers were doing this but still missing a secret sauce I’m afraid… https://playground.babylonjs.com/#S7E00P#45

Can’t get the animations to play different animations when cloned :exploding_head:

I guess you might miss this part : Babylon.js/assetContainer.ts at master · BabylonJS/Babylon.js · GitHub

Mainly this one: Babylon.js/assetContainer.ts at master · BabylonJS/Babylon.js · GitHub

1 Like

Yeap, you are correct! I was suspicious of that part as well, but didn’t have time to test it yet :slight_smile:

Here is the final version, with added animation blending!

So what I gather, here is what needs to be done if you wish to clone a fully rigged and animated character “manually”. I also assume there might be some differences if the glb/gltf formats are not used…

  1. You need to store the root mesh, the skeleton and the animation groups somewhere.
  2. Clone the root mesh using instantiateHierarchy, with the doNotInstantiate -option. You also need to store the links between the original mesh parts with the cloned mesh parts.
  3. Clone the skeleton with the regular clone function.
  4. Set the cloned root mesh as skeletons overrideMesh if skeleton already has this pointing to somewhere (as in the original mesh, so it needs to be replaced).
  5. Fetch all the descendants of the rootMesh with getDescendants (with false as option)
  6. Set the cloned skeleton as the skeleton of all the descendants.
  7. Link all the cloned skeleton bones with the new cloned root mesh. You need to use the stored links created in section 1.
  8. Clone each animation group separately using the clone function. This works a bit differently than normal clone, since you need create a special conversion function to set the animation group to a new target, which is some part of the new cloned root mesh hierarchy. Here you need the stored links as well from section 1.
  9. Done! You can use your cloned animation groups to play animations separately :slight_smile:

Have to say that I really love Babylon community :heart: Thank you all for helping me!