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:
Load the character glb file with AssetsManager
Save the result for easy access and future use on my own plain JavaScript object
When needed, fetch the character model and animations and play one of the many animations
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.
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
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: https://playground.babylonjs.com/#S7E00P#43
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 … I am also using Mixamo animations, so I wonder if they do something naughty to the model itself?
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?
Yeap, you are correct! I was suspicious of that part as well, but didn’t have time to test it yet
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…
You need to store the root mesh, the skeleton and the animation groups somewhere.
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.
Clone the skeleton with the regular clone function.
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).
Fetch all the descendants of the rootMesh with getDescendants (with false as option)
Set the cloned skeleton as the skeleton of all the descendants.
Link all the cloned skeleton bones with the new cloned root mesh. You need to use the stored links created in section 1.
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.
Done! You can use your cloned animation groups to play animations separately
Have to say that I really love Babylon community Thank you all for helping me!
Hi, just want to pass my just acquired knowledge to everyone who will come to this thread searching for help with animating cloned characters with multiple meshes, in this case root + model mesh. You can download model here and preview it in sandbox to see what this “root + model mesh” means.
You need to store the root mesh and model mesh, the skeleton and the animation groups somewhere.
Clone the root mesh and model mesh using instantiatehierarchy, with the doNotInstantiate -option. You also need to store the links between the original mesh parts with the cloned mesh parts.
Clone the skeleton with the regular clone function.
Set the cloned skeleton to model mesh
Fetch all the descendants of the Model mesh with getDescendants (with false as option)
Set the cloned skeleton as the skeleton of all the descendants.
Link all the cloned skeleton bones with the new cloned root mesh/model mesh. You need to use the stored links created in section 1.
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/model mesh hierarchy. Here you need the stored links as well from section 1.
Done! You can use your cloned animation groups to play animations separately
As an absolute newcomer to 3D models/Babylon.js I struggled for many hours with this, try-failing many there-and-back changes in the code, so I hope this will ease others journeys
This is an old thread so it might be worth mentioning that we now have an instantiateModelsToScene function that can duplicate a loaded asset container with a single call.
Yeah, could update the playgroynd at some point for the assetContainer method (if you don’t have time to do it) I think there was some hassle that I didn’t use the assetContainer back in the day
Coming back to this, assetContainers feel a bit tough to deal with in my game example. I don’t think there is a specific method in the assetContainer to get a specific model to the scene.
I would like to use asset container as a pool of assets where I can get a specific model instantiated using a specific key. For example, I want to load 20 assets to the asset container, and just instantiate the player model. The instantiateModelsToScene just seems to insert all the models of the asset container to the scene.
I could use the assetContainer so that I only add one model to it, but it still gives me a list of nodes and feels a bit awkward to use. To me kind of feels that assetContainers haven’t been thinked through, or that I am really missing something
I’m about to deep dive into this thread to figure out what magic you guys are doing above. But one thing that’s weird about the examples in this thread. If you go to inspector, open Animation groups - and play/pause the groups individually, the behavior is odd. Sometimes both characters stop. Sometimes they don’t restart on play. Sometimes one plays and the other stops.
Is it just that the inspector isn’t capable of starting/stoping the clones via the Animation Group name, given the way they were cloned?
And second question: is all the data from the animation groups doubled? If i cloned 100 characters, is the animation data replicated? Or some kind of pointer created?