Animate multiple Ready Player Me avatars in the same scene

I’m trying to animate multiple Ready Player Me avatars at the same time with different animations, but I’m having issues trying to allocate animations to avatars.

I’ve created a very simple demo where:

  1. I’m downloading a first RPM avatar.
  2. I’m downloading a second RPM avatar.
  3. I’m downloading 3 animations (“BreathingIdle”, “Running”, “Walking”).

These 3 animations seems to be automatically attached to the first RPM avatar downloaded (importedRPM), so I just start the first animation (scene.getAnimationGroupByName(“BreathingIdle”)) on that avatar:

BABYLON.SceneLoader.ImportMeshAsync("", "https://api.readyplayer.me/v1/avatars/", "63354b2d7ca7d77c3a5febc1.glb", scene).then((importedRPM) => {
    BABYLON.SceneLoader.ImportMeshAsync("", "https://api.readyplayer.me/v1/avatars/", "621dfdd170f4fcd078c26671.glb", scene).then((importedRPM2) => {
        BABYLON.SceneLoader.ImportAnimationsAsync("https://talk-q.com/", "animations.glb", scene, true, BABYLON.SceneLoaderAnimationGroupLoadingMode.Clean, null).then((importedAnimations) => {
            const anim = scene.getAnimationGroupByName("BreathingIdle");
            anim.start(true, 1, anim.from, anim.to, false);
        });
    });
});

However, I’m not able to allocate this same animation to the second avatar (importedRPM2).

Checking on Babylonjs documentation and on several posts in this forum, hasn’t really helped so far. I’ve tried many different techniques, but none seem to work.

I’d be grateful if anyone could help me here.

Thank you!

Hello and welcome to the Babylon community! You’ll have to clone the animation group and retarget the bones in the cloned animation to correspond to the other avatar, here’s an example by @PatrickRyan Retargeting Animation Group | Babylon.js Playground (babylonjs.com)

1 Like

You also have a problem with the animation structure.

In animations.glb you have 3 targeted animations (the last 3) which target a root node named “BreathingIdle”, “Running” and “Walking” for the 3 animations “BreathingIdle”, “Running” and “Walking”, respectively. But the avatar meshes have a “Armature” root node instead, leading to target === null in these cases.

So, you should retarget those 3 targeted animations to the right node instead:

const avatar1 = importedRPM.meshes[0];
const avatar1Armature = avatar1.getChildren((node) => node.name === "Armature", false)[0];

for (const ag of scene.animationGroups) {
    for (const ta of ag.targetedAnimations) {
        if (!ta.target) {
            ta.target = avatar1Armature;
        }
    }
}

This will retarget to the “Armature” node of the first avatar.

Then you should clone the animation groups and retarget them to the 2nd avatar, as @carolhmj said:

const ags = scene.animationGroups.slice(0);
for (const ag of ags) {
    ag.clone(ag.name + "2", (oldTarget) => {
        return avatar2.getChildren((node) => node.name === oldTarget.name, false)[0];
    }, true);
}                

Here’s the full PG:

4 Likes

Thank you very much for your support, @Evgeni_Popov and @carolhmj!