Creating a Dynamic Run/Walk Animation

I’m looking to give my mesh a run animation where the direction of the legs change depending on the joystick direction.

Let me explain in detail, imagine a thumb stick on a game controller. When the thumb stick is pointed up/forward, I want the character to run forward so the legs should be pointed the same way. Here is an example:

Notice the legs are pointed forward. Now if the thumb stick is pointed to the left, I want the character to run to the left so the legs should be pointed likewise.

The benefit of this is that I only need to make one run/walk animation and I can just rotate the legs to match the direction of the thumb stick. It would give a nice analog visual movement to the legs because they can point towards any direction. Also it’s worth noting that when I say they’re pointed toward the left, I mean they’re pointed toward the left relative to the upper body namely the torso, arms and head. The upper body is rotated with the other thumb stick.

My question is how would I implement something like this?

Here’s what my intuition tells me. In my animation software (Blender), I’ll animate the player as if he’s running forward. Now because I’ll have an armature bone hierarchy like the following, if I rotate the pelvis in game using mesh.skeleton.bones[pelvis].rotation, the legs will rotate as well.

This only works if the key frame data for the bones (position, rotation and scale) is relative to the parent. So would this work? Can I programmatically rotate the pelvis and have the animation for the legs work as expected all with one armature?

Thanks

You can manually rotate/move bones, if you rotate the first bones of your 2 legs the animation will proceed rotated hierachically - but it also depends on your animation keyframes, i use Cinema4D which only exports rotations there are no position keyframes, basically with IK. I do this for some motions too, especially pelvis/head rotations.

If there’s a position keyframe in the legs it’ll probably disturb the animation (except if they are relative), if there are position keyframes on your pelvis where the legs are connected to it would be fine.

Okay, I see. How would I handle having multiple animations though? Let’s say the player can either have a gun with his right hand or not. He can run or not, throw a grenade with his left hand or not and shoot the weapon or not. It seems to me that if I use one armature I’ll have to create 12 different animations:

  • idle
  • idle with gun
  • idle with run firing
  • idle while throwing
  • idle while throwing and with gun
  • idle while throwing and with gun firing
  • run
  • run with gun
  • run with gun firing
  • run while throwing
  • run while throwing and with gun
  • run while throwing and with gun firing

This seems rather absurd because there will be so much duplicated data. All of the animation key frames for the legs will the same regardless of if the player has a gun, is throwing a grenade, shooting the gun, ect. the only different is if the player is running or idling.

What if I created three separate armatures? One for the “main body” that contains bones for the torso, pelvis, left leg and right leg. One for the left arm and one for the right arm. Then, instead of duplicating a bunch of key frame data I could give the armatures the following animations:

Main body - idle, run
Left arm - idle, run, throw
Right arm - idle, run, hold gun, hold gun firing

Is something like this the correct way to go about giving the player mesh multiple animations?

Yes you can animate them separately and later mix them by playing all required, so you can mix any feet animation with any arm animation etc, you just need to make sure when you create your run animation for example, to not record any keyframes on all other bones you want separated (only feet bones).

In C4D i lock all other bones in this case, as i use IK goals which bake the keyframes and it coud accidentally move and record unwanted bones, just a hint if your modelling software does such things.

@Fyrestar Just to clarify, in my modeling software I can do this using only one mesh but with multiple armatures?

You can use a single mesh and a single armature/skeleton. For example frame 0-20 only feets walk animation, 20-40 only feets run animation, 40-50 only right arm throwing animation, 50-60 only right arm whatever. So later you can play any feet sequence with any arm sequence at the same time.

@Fyrestar Okay thanks for the help.

I have a new issue though, how do I disable bone constrains for a specific action in Blender? Or how do I lock bones that have an IK constraint on them? Basically like @Fyrestar said, when I make a run animation it creates unwanted bone movement in the arms because of how the armature is set up. I can’t simply remove the IK constrains because I need them to animate the arms. If I could remove the arm IK constraints only for the run action that would work I think, I’m not sure that’s possible though. I might have to ask the Blender community…

In C4D i can disable bones or IK tags, i’m sure you can disable IK targets in blender too as far as i remember. (like disabling all targets except left and right leg)

Okay for the time being I made a really simple model and rigged it with no IK constraints or anything fancy.

Then gave it an idle animation, making sure not to mess with the arms.

Also gave it a throw animation, making sure not to mess with the legs & torso.

I wanted to see if I could play the throw animation while the idle animation plays in three.js. It doesn’t work though, when the throw action plays it seems to reset the idle action.

I’m not sure what I’m doing wrong. Here is my minimal code example.

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );

var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

camera.position.set(2, 1, 2);
camera.lookAt(new THREE.Vector3(0, 1, 0));

var clock = new THREE.Clock();

var loader = new THREE.JSONLoader;
var mixer;
var throwAction;
var set = false;

loader.load("./player.json", function(geometry) {
    var material = new THREE.MeshBasicMaterial({skinning: true});
    var skinnedMesh = new THREE.SkinnedMesh(geometry, material);
    scene.add(skinnedMesh);

    mixer = new THREE.AnimationMixer(skinnedMesh);
    var idleAction = mixer.clipAction(geometry.animations[0]);
    throwAction = mixer.clipAction(geometry.animations[1]);
    throwAction.setLoop(THREE.LoopOnce);
    idleAction.play();
    set = true;
});

document.onmousedown = function() {
    throwAction.reset();
    throwAction.play();
}

function render() {
    if(set) {
        mixer.update(clock.getDelta());
    }

    renderer.render(scene, camera);
    requestAnimationFrame(render);
};

render();

source

1 Like

They are both playing mixed, probably just setthrowAction.time = 0.0; instead reset and play, the last frame should also get recorded of the throw animation. I’m on tablet currently, sorry.

@Fyrestar using throwAction.time = 0 instead of throwAction.reset() and throwAction.play() doesn’t work. Also what do you mean the last frame of the throw animation should get recorded?

I haven’t found a solution to this and it looks like others in the community have had the same question with no answer unfortunately.

https://stackoverflow.com/questions/41281001/three-js-play-multiple-animation-in-same-time

I can’t help much with blender sorry. The last frame should get recorded to close the loop, looks like it plays both as wanted, but resets when the throw animation ends.

@Fyrestar Making the throw animation a closed loop doesn’t fix it.

Perhaps this is some sort of bug? Should I consider posting an issue to the three.js repo?

I can do mixed/merged animations, but i use C4D and a custom format, don’t know what blender exports - anyway it seems to work partially but the throw finish reseting something. You could open a issue, sure. Maybe provide the robot test model too.

I created an issue on github about this problem which you can find here:

Although I’ve closed the issue, I still haven’t found a solution. Thanks to the help of jostschmithals I now know that the issue isn’t related to the three.js animation system but instead a problem with exporting the model and it’s animations to the .json file.

So here is how I’m exporting everything. I make sure only the mesh is selected and that the armature is in pose position.

Now I’ve seen a lot of people say that the mesh should be in rest position but when it is, the animations don’t export correctly.

Then I use these export settings.

Can anyone help me figure out the proper way to export a mesh with multiple animations in blender so that I can mix them together in three.js?

Hi, I was looking on this question for a while on my side and could not find a solution. I do export as you do from blender and would like to mix animations with dynamic bone control. Perhaps could we exchange our experiences. The first point I would share is regarding the NLA editor in blender ; do you agree blender allows to do dynamic bones management in the NLA editor but when exporting the animations to json, all bones are exported for each animation. So when mixing them in three.js, all bones positions rot and scl are calculated from all these data.

@derivou

do you agree blender allows to do dynamic bones management in the NLA editor but when exporting the animations to json, all bones are exported for each animation.

I’m not really sure what you mean by dynamic bone management in Blender, you just give bones key frames and then the key frame data is only applied to that bone so you can have different actions on your armature in Blender where only certain bones have key frame data.

As far as my experiences go I honestly haven’t done too much because I’ve been busy with college summer classes unfortunately but I would like to share a few things with you and the community about this topic.

After trying to mix different animations together I’ve concluded that it’s just not viable to do in three.js with the Blender exporter. The reason for this is that the Blender exporter is really bad when dealing with animations. You cannot do something as simple as have a character walk and shoot a gun where those animations are separate and exported using the Blender three.js exporter. You might be able to do this with different animation software and thus a different exporter I’m not sure. I also want to stress that you are able to mix separate animations just fine in three.js, you just can’t obtain the animation data to do this via the Blender exporter.

This reason for this is because the Blender exporter will export all of the bone data instead of just the bone data that pertains to the action. For example, let’s say you make a walk animation in Blender. You’re only going to have key frame data for the legs but blender will export key frame data for all the bones, not just the legs. This means in three.js when you play the walk animation the animation system will animate every bone instead of just the legs which is obviously a problem when you’re mixing multiple animations together.

I set out to make my own exporter that would only export the key frame data for the bones that pertain to the action but haven’t made much progress because of class like I said. In the .json file after you export your mesh you could probably delete the unnecessary bone information by hand and see if that works.

So that’s my experience with mixing separate animations, until the Blender exporter can do what I said I think you’re going to have to either make your own or try deleting the extra key frame data for each action by hand. If you decide to do either one and get it working, let us know!

Thank you for these clarifications. What you are describing is exactly what I’m experiencing too. So at least I feel it more understandable. The main point is related to the export of ALL bones pos/rot/scl whether they move or not and are then mixed with those which are moving. My need is related to a platform to make movie mockups with animation (animatics and story board) so I utilize a library of 3D objects including objects movement capabilities. My intention is now to see if it is possible to modify the result of the export to eliminate the data for “still bones”. But I’m not sure if this is really achievable because I dont know how the animation engine works and if it accepts to have null or nothing for certain bones in the hierarchy. I already included a visual representation of the animations (like the curves view in Blender) and will test what happens if I delete some data. I’ll keep you posted if I have any positive result.

Hello, here my progress : I tried to remove the “still bones” from animation. Actually the JSON loader produces à structure : geometry.animations and each animation is an object with name and tracks. Tracks is an array of objects with names times and values. Each track is a bone movement (position, rotation quaternion or scale). When the bone is “still”, times and values include only begin and end data. So, I tested replacement of these tracks by null or 0 but this does not work. I guess, by definition an animation has to provide the complete position scale and rotation for all bones and local animation can be done by morph animation (this is at least the only exemple I found in the exemples library : the knight). So, now my intention is to go another way : include into my code a new function called in the redering loop to animate only those bones I want to move. Therefore we have SkinMesh.skeleton.bones[i].position.set function (same for rotation / Scale) and hope to come to better results.

@derivou It should work if you remove the keys that don’t change. For example:

"animations":[{
        "length":5,
        "name":"idle",
        "hierarchy":[{
            "keys":[],
            "parent":-1
        },{
            "keys":[],
            "parent":0
        }
...

Just make the keys an empty array. I can post a working example if you’re still having trouble.