The way your avatar moves in a game is probably one of the most important aspects of a smooth gaming experience and the foundation for all the other animations that you add to it. If it’s fluid and responsive you don’t even notice it, but if it’s jittery and slow, it can ruin an otherwise good game.
As a player, your challenges in Twelve Minutes are about understanding the available options to a situation (and how they will affect your surroundings), rather than split-second twitch decisions, and that allows me to have extra room for the movement to feel more naturalistic. The game is also using a click-to-move system (like the old point-and-click games) rather than immediate input (like 2D platform games) making it easier to have organic transitions since I don’t need to do give you a millisecond response to your controller/input.
Super Meat Boy is a great example of very precise split-second movement:
As opposed to something like Thimbleweed Park, where you could be sipping a cup of tea with one hand while playing with the other:
Still, you need to be able to get an immediate feedback to your inputs, even if I want to keep the animations somewhat naturalistic and that’s what I’ve been doing over the last month.
For those that remember my last post about animation over a year ago, when I was figuring out the basics of actor movement, I went with root motion because I wanted to prevent any sliding. Unfortunately, that created too many constraints, since you are limited by the range the animation gives you, and since the gameplay space is so small, I need a lot more precision.
My initial plan for Twelve Minutes was to hire an animator and just have them do keyframe animation, but I realized the amount of nuance and personality required, as well as the high amount of animations needed (locomotion alone was 100+ animations), was just unfeasible for the budget I have so, I started to wonder if I could use motion-capture.
If I could figure out a way to record the actors doing the animations, and easily implement then in-game, then I could save a lot of time and get the natural nuanced movement I’m looking for.
Even though I’ve been in the industry for over 10 years, and I’m aware of the difficulties of recording and implementing motion-capture, actually being responsible for the whole process is kinda scary. Most AAA studios have their in-house mocap solutions/team, and if you are doing a one-off session while contracting an exterior mocap studio, you bring your Animation Lead, Director and hire actors and these tend to be very expensive and technically demanding. So doing this on an indie developer scale has always been practically impossible.
Two years ago, while at GDC, I ran into a good friend (easily the most experienced animator I’ve ever worked with) and he told me he had just started his own motion-capture studio, MocapNow.
I explained to him what I had in mind, and my complete lack of experience on that subject, and he was not only able to put me at ease, but his studio was perfect for my needs. Not only we are able to record sessions remotely but also to quickly integrate them back into the game with minimal work.
After some testing, it was time to schedule the first official session and record all the locomotion animations. The whole session took only 2.5 hours and in the video below you can see how it went from my point of view. The top image is the actor in the suit, and below is a real-time preview duplicating the movement and matching the camera of how it will look for the player in-game. Ideally, I would be using the final game characters, rather than the generic model, but they aren’t ready yet.
Due to the size of the environment, and to be sure movement feels natural, I split the locomotion into two different modes based on how much distance you cover:
Short distance – Moving to a destination that is so close that you only need one footstep (anything closer than 0.75m).
Long distance – Anything further away that requires you to start walking and then stop (anything further than 0.75m).
If you are in a closed space and want to interact with something behind you (e.g. a light switch), we do a side-step and turn towards the destination in one single move:
In order to cover every possible combination, we defined a circle of 0.5 meters and divided it into 8 rotations. For each rotation, we also subdivided it into 8 possible end directions. This means that any movement the actor has to do is covered by one of these animations:
It’s not feasible to record every possible angle when doing motion capture, but in-game you can and so we have to load the closest animation to the angle you are turning. Using the image above as an example, the 45° position would cover any rotation between 22.5° and 67.5° in-game. The downside is that when you play the animation at an extreme angle, you inevitably get some foot sliding, something that I had to figure out a solution for (more about it below).
For long distance animations, since the amount of space you cover is variable, the walking cycle is split into three states:
Turn To Walk – Character turns and moves towards the walk direction. Split into 8 angles just like the side-step. Below is a “Turn to walk 90° to the right”.
Walk – Loopable walk cycle to cover the variable walking distance.
Stop Walk – Once the actor is close enough to the destination, it transitions the walk to the Stop Walk for a smoother end movement. It also has variations for rotation, so you stop and rotate at the same time (e.g. when you walk towards a couch to sit down, as you arrive, you turn 180° in order to sit). Below is a “Stop Walk, turn right 45°”.
The other challenge is to make sure the transitions between the different animations are smooth. The Short Distance animations are one single take, so no need for transitions. The Long Distance transition from Turn to Walk to Walk is straightforward since I know the end pose of the Turn to Walk and so can match it with the start pose of the Walk.
The problem is trying to get a natural transition from Walk to Stop Walk, since you can interrupt the walk cycle at any moment. Here is how it looks before it’s fixed:
The best solution I found, was to first record the Stop Walk with 4 distinct feet positions so I can choose which one is the closest to the currently interrupted walk cycle pose. So for every Stop Walk we have 4 start poses: Contact Left Foot / Contact Right Foot / Passing Left Foot / Passing Right Foot. (In the video just above, we have it starting with a Passing Left Foot).
The next step is to mark the feet position in the Walk Cycle so the game knows which one of the four Stop Walk animations to use (in the video below, I marked it using “Events” in the timeline):
This way, you end up getting a smooth Stop Walk, no matter when you interrupt the Walk cycle:
The last problem to solve was to make sure there was no foot sliding. I’m going to use the Short Distance sidestep forward animation to illustrate my solution.
Since the same animation is played no matter how large the distance is(from 0 to 0.75 meter), the game will slide the actor root transform towards the destination to make sure the actor ends at the right position and so, the feet will slide as the actor moves. In the example below, he is moving the maximum allowed (0.75 meters) and if you watch the right foot, you can see that it slides forward, even though it should be in place:
The solution is to force the feet to stay in place if they are in contact with the ground in the original animation, even if the root transform is moving the whole actor. To do so, we use Inverse Kinematics (IK), allowing us to overwrite the original foot position from the animation to whatever we want it to be while adapting the skeleton hierarchy position:
But for IK to work, it needs to know when the foot is supposed to be in place, and for that we used curves. Based on the animation clip, I created two curves (one for each foot) and added a ‘weight’ of zero if its moving and one if I want it to be in place:
And once I apply that weight to the IK foot node, we get smooth movement without any food sliding no matter what the distance is (video below covering 0.75m as before):
And here is how the whole system currently feels in-game :