September 22, 2017

A Layered Approach to AI Locomotion in ‘The Occupation’

By James Burton


Hello, this is James Burton - Technical Artist at White Paper Games. This post intends to show the process we used to create the locomotion system of our AI characters in our upcoming game The Occupation.  I worked on this system with; Jonny Pickton, our AI designer, Robert Beard, our animator, and Martin Cosens, our programmer.  We should preface this by saying that we, as a team, had never had any experience with character animation (or characters at all for that matter!) prior to making this system. We don’t claim to be pioneering this work, we simply landed on a solution that worked for our project, and we thought it’d be good to share with you all. We’d love any feedback or comments on how we could improve our setup! Our contact info is at the bottom of this article.

The key things we needed from this locomotion system were:

  • Modular, non destructive elements (adding or removing layers wouldn’t mean the character would stop working or affect the other layers).
  • A small coding requirement since we only have one programmer.
  • A proper tone as our game has no combat and the AI is calm and observable. Strafing animations won’t work.
  • A system that sticks to UE4 defaults as much as possible.
  • A system that sticks to constant speed and Turn Rate where possible.

Before doing this, we tried a couple of other methods:

A Full Root Motion Setup: Looked great, however, didn’t give us the precision we needed for our AI to complete other tasks.

Root Motion/ Capsule Driven Hybrid: Used Root Motion for turns and capsule driven movement for everything else. Blending between Root Motion velocity back to capsule was problematic at the time – decided to ditch it.

In the end, we went for fully capsule driven system with a couple of tricks that allowed us to match the speed of the capsule to the animation playing – but more on that later.

In any case, here is what the UE4 defaults look like with no editing. You can see the character just has a walk cycle and navigates the scene, but doesn’t exactly look natural:

So here’s our attempt at fixing this.

Layer 1 – Turning on the Spot

First we focused on getting the base layer setup. This way, designers could work with the characters and we had a basic level of fidelity. For us, this meant getting the character turning on the spot to face the next target point in the Nav path:

  • Animations were authored to a constant rotation rate.
  • We scaled the Play Rate of the animation depending on the angle the character needs to turn. To do this, we divide the angle we need to turn by the rotation rate of the character. This gives us the desired rotation time for the turn. We then divide length of the original animation (in seconds) by the desired rotation time and this will become the Play Rate of the animation for the turn.
  • It’s a very basic setup, might even be shippable for some games.

Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FIMG1_PlayRateFormula-770x132-40cf6c29f58fbaa0033e828f464617ccc7d473e3
Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FIMG2_ScalePlayrateforSpotTurns-770x175-98be8e33b4c57bc70b85d6a9b95c2c021713904a

Here is a video with the result, as well as some GIFs with the authored animations for this layer:

Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FGIF1_-TurnonSpot45-6b7174660396fbf8fd3f40b479cd6b6ec61d4752

   Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FGIF2_TurnonSpot90-073c83b7a4226c2fc49d361f7e961acb6f1e0a51Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FGIF3_TurnonSpot180-e4e18cc4f6b2d412ec8dfa69909f45e3b26d9a21 







  [Turn On Spot 45]             [Turn On Spot 90]         [Turn On Spot 180]

Layer 2 – Walk Starts

The next layer would consist of walk starts – this way the character could accelerate into the base walk speed without just popping into it. Since we’re dealing with acceleration here, and we wanted to keep everything capsule driven, we wrote a small tool. It’s very simple, since my experience with coding is very, very limited it was made in MEL. The tool writes a curve that describes the character’s speed at each frame, mapping the acceleration. So how does this work? Well, we let our animator make an animation and then sample through it with simple maths:

Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FIMG3_Speed-Formula-770x132-88308d0bf30bd9c23e0257059d7cb20906cad618

Please note that TranslateX.F2 – TranslateX.F1 simply means subtracting the current frame to the previous frame of the anim, to work out how much movement there has been between the frames. We then divide that by the time it takes to go through one frame at your desired FPS (some animators work with 24fps, others with 30… etc).

Thankfully, we can key this data to an attribute on our Skeleton’s Root Bone and when importing into UE4 make sure “Import Custom Attributes” is on. This will ensure it comes in as a curve in the animation asset. I should mention this is SUPER cool feature in Unreal Engine that opens the doors to a lot of other cool setups!

Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FIMG4_CustomSpeedAttribute-770x136-807d4ff0104f8ea1c74066bf17f4dbdc1777ca83

We then use this Curve to set the max speed of the character, and we’re good to go!

Here are the results of this as well as some GIFs of the authored animations:

Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FGIF4_StartWalkFWD-825c8ec73e8e1cb5fa734fb78a7286463a763b0aUnreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FGIF5_StartWalk90-a82bd63e1a2266b368bc4147c1e2fad50705c5a4 Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FGIF6_StartWalk-90-aa415b13dc1ba39be1fcdcf4a87b6aef44304537             







 [Start Walk FWD]              [Star Walk 90]                  [Start Walk -90]

Layer 3 – Walk Stops

This one is pretty simple since the setup for it is exactly the same as the Walk Starts, however, in order for the character to know when to start playing the “Stop Animation” we needed our programmer to write a bit of code in UE4 to get it working.

The code checks for the last point in the path, and fires an event to “play stop animation” at the required distance from the end point (This is specified by our animator when making the animation, but try to keep it short!).

There’s a tiny bit of foot sliding due to the acceptance radius of the final point – In the example below it’s noticeable, but with a bit of tweaking you can get it just right. For us it was important that the character reached the final point perfectly since other animations will play off that, so we snap them to the point if there is a bit of error to make sure the rest works well.

Here is the video of the Result as well as a GIF of the authored animation:

Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FGIF7_WalkStopFWD-2362243ea8baeb8abf63c7e2146448b9f023f6ea

[Walk Stop Forward]

Layer 4 – Faking Curved Paths

This was the toughest issue to fix and required a bit of code, but it’s also the layer that makes the biggest difference in the overall look of the locomotion system.

Here, we essentially take the character off the nav path and allow her forward vector to drive her movement while she turns until she faces the next point. This is better explained with an image so here it goes:

Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FIMG5_TurnExplanationImage-770x770-e93ebd25ac4ef7413b9c28c7a9e8f2015a8e60bd

The important thing is to take advantage of the constant rotation and speed of the character capsule – it makes the maths easier.

Here is a video of the result:

Luckily we didn’t have to author any animations for this as it looked fine without them!

Layer 5 – Turn Anticipation (Oh! A piece of candy!)

This was a nice add-on in order to make the character feel like she was anticipating a turn. For us, this consisted of having her slightly turn her head and body in the direction of the turn before she actually started turning.

This required a little ingenuity, since we couldn’t simply use her next point and Lerp the rotation towards it.

We ended up making a system that uses a “lure” that Lerps between the Nav points ahead of the character and makes the character’s body and head always aim towards it using an AimOffset. In the example below you’ll see a yellow ball that the character is constantly chasing after (unfortunately she can never get it! Hehe).

Here is the result as well as the Blueprint setup for it and a GIF of the Aim Offset:

Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FIMG6_PieceOfCandySet-770x223-be0a1732766d1d33c4c9e3ab2882745a0351a344

Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FIMG7_PieceOfCandySet_2-770x211-e0d79bd178843175c1f2cd5a130df762bcc13341

Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FGIF8_WalkLeansAimOffset-ec813037004b2ac7b6e013c0ad0a6fc92253f623

[Walk Leans Aim Offset]

So there you have it, this is the locomotion system we’re using in The Occupation. We’ll leave the final AnimGraph for this setup below as well as a video with the comparison of a path traversed with Our Locomotion system vs UE4 Defaults.

Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FIMG8_AnimGraph-770x390-e9a679c94be1f88c5a2c671f1bd5edef3bc387cd

Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FIMG9_AnimEventGraph-770x297-2e54738a785f965abcb9e89e97150f681b663480

We hope this is useful to you, and if you have any questions or comments, please leave them below or feel free to reach us through Twitter (@whitepapergames) or email us at [email protected].