In my previous devlog I explained the main character’s animations that I created in Blender and exported to Unity. In this devlog I will talk about procedural animations of the main character’s abilities which are completely or partially created and controlled from the code inside Unity.

Spider Legs

In King, Witch and Dragon the main character has ability to stick and crawl on the walls and the ceiling. The walls don’t need to be strictly vertical and ceiling is not necessary horizontal.

Visually this ability represented with spider legs that grow from the character’s back when he lands on the wall and disappear when he performs wall jump or crawls to stable ground.

Spider Legs Concept

I listed all the parameters that each spider leg should have. I created Scriptable Object that stores all these parameters (later I will explain why I decided to put them inside scriptable object instead of prefab).

Spider Leg Parameters

Spider leg itself is just IK chain with Empty GameObject called target. All the following game-logic will be focused on finding proper position for the target on the surface and transitioning to this position in the right moment.

Choosing the moment to take a step

To start I created 1 single spider leg on a flat horizontal surface. First of wall we need to keep the target (the tip of the spider leg) in specified range. This is how it looks:

Spider Leg Range Logic

Simplified code for this logic looks like this (in real game it’s a bit more complicated):

private void UpdateLeg()
{
    // Calculating distance to IK target
    float dist = (_currentTargetPosition - transform.position).magnitude;
    // Compare it with min and max limits
    if (dist > maxDistanceFromRoot || dist < minDistanceFromRoot)
    {
        // If the target is out of range find new point and take a step
        GetNewTargetPosition(_profile.defaultRaycastDistanceFromRoot);
        StartCoroutine(MovetargetToNewPosition());
    }
}

Find new point on the surface

Because the surface that the character is crawling on can be rotated to arbitrary angle we cannot just simply do a raycast up/down/left/right. Instead, we need to draw imaginary circle around spider leg root and find a point where this circle intersects with the surface. Standard SphereCast and CircleCast won’t help us because we need to know exact point on the circle and not inside of it.

To find this point I’m using sequential LineCast that follows sectors with fixed angular step:

Circular LineCast

The function that implements this approach looks like this:

private bool GetNewTargetPosition(float distanceFromRoot)
{
    // Assign default target position as new position
    _newTargetPosition = transform.TransformPoint(_targetDefaultPosition);
    // Determine start and end point for LineCast
    var linecastStartPos = transform.up * distanceFromRoot;
    var linecastEndPos = linecastStartPos;
    // Rotate end point to specified angle around root
    var rot = Quaternion.AngleAxis(raycastAngularStep, transform.forward);
    var steps = Mathf.CeilToInt(180 / Mathf.Abs(raycastAngularStep));
    // Looping through LineCasts until it finds any point
    for (int i = 0; i < steps; i++)
    {
        linecastEndPos = rot * linecastStartPos;

        if (Physics.Linecast(
            transform.position + linecastStartPos, 
            transform.position + linecastEndPos, 
            out RaycastHit hit, 
            climableWallsLayerMask))
        {
            // Point found, exiting function
            _newTargetPosition = hit.point;
            return true;
        }
        linecastStartPos = linecastEndPos;
    }
    // Point not found, use default position
    return false;
}

To move target to new position I use coroutine. To add easing to the leg movement and also define vertical offset from the surface I use Animation Curves in the Inspector.

Spider legs synchronization

With 1 spider leg everything looked fine until I attached 4 legs the the main character…

While he was moving on flat surface everything was fine, but after changing surface angle or moving around a corner the relative position of the legs and steps timings went completely off. Sometimes he performed steps with 2 spider legs on the right then with 2 spider legs on the left. Even worse, sometimes all 4 spider legs decided that right now is a perfect moment to take a step and detached from the surface. So I had to find a way how to synchronize them.

At the beginning I tried to move only 1 spider leg at time and put other in the queue to wait until the first one finished. It solved some problems but not all of them (they didn’t detach altogether anymore, but still could mess up the order of the legs to take a step).

At the end I created 2 groups of spider legs, each contains 1 leg on the left and 1 on the right. If 1 of the legs in the group wants to take a step, the second leg in the same group forced to take a step as well. So 2 spider legs, one from each side of the character, take step simultaneously. Meanwhile other group is restricted to take a step.

I create 4 Scriptable Objects with Spider Legs parameters and in each of them slightly changed some values (transition time to new position, max vertical offset, min and max range limits, etc.). Using this approach all 4 spider legs move slightly different.

With this approach I can create as many different profiles for spider legs as I want. I don’t need to create new prefabs or prefab variants, just drag-n-drop new scriptable object to the prefab instance. This also allows to edit values in Play Mode.

The final result (with character animation placeholder):

Spider Legs Procedural Animation

Character animation

I received several comments that it would be cool if character would change his position and rotation depends on the angle of the surface he is crawling on (bend, face towards the wall, play arms climbing animation alongside with spider legs, etc.). It all sounds cools, but I was thinking about it more from gameplay perspective.

I wanted to give character ability to fight while on the wall. At least perform sword attacks in 4 directions (up, down, left and right). Adding contextual crawling animations + attack animations from different positions would significantly increase level of complexity and scope of the project.

I decided that gameplay freedom is more important than visual appeal (in this particular case), so the character will always stay vertical while on the wall and will perform attacks from this position.

For the character animation I used animation blending depends on move speed.

I created 5 looped animations:

  • idle on wall
  • crawling up the wall
  • crawling down the wall
  • crawling left on the ceiling
  • crawling right on the ceiling

Character crawl animations

In this pose character is facing camera and holding his sword with 2 hands. From this position it should be easy to attack in all 4 directions and also character can grab the sword with different hands depends on attack direction.

When character is on wall or ceiling he can crawl not only left-right or up-down but in any direction depends on the surface angle. I used 2D Blend Tree that takes horizontal and vertical speed for animation blending:

2D Blend Tree

The result:

Character crawling animation blending

Extra stuff

I also added ability to crawl on moving and spinning platforms:

Crawling on spinning platform

Crawling on moving platform

Viper Strike

In a nutshell it is quick dash to short distance. During this time the main character transforms into snake.

Viper Strike Concept

Main character can dash in 8 directions (up, down, left, right and 4 diagonals).

The interesting part starts when the character tries to dash into narrow passage or tunnel. The character will stay in the form of a snake until it exits the tunnel. Tunnels can have turns and curvy shapes.

The goal was to make snake’s tale correctly follow the head’s trajectory and stay in the tunnel.

Mixed approach to animation

In previous case with Spider Legs all animations were procedurally created in Unity. In this case I used different approach when animation partially created in Blender and then modified and extended from code inside Unity.

Rig and animation

To start I created looped crawling animation in Blender. I created 2 sets of bones for the snake. The first set to create this wavy/spiral crawling animation. The snake’s mesh is skinned to these bones. The second set will be controlled from code inside Unity to follow head’s trajectory. Each bone from the first set is a child of the corresponding bone from the second set and animated relatively to parent bone.

Snake crawling loop

Yes, I know that snakes don’t crawl like this :) But this spiral animation looks much better from side-scroller perspective and makes a bit more sense when the shake is dashing in the air.

Then I integrated it to get simple dash (without any transition yet):

Snake dash no transition

Procedural animation

The first idea was to just attach spherical colliders to the tail bones, connect them with the hinge joints and let the physics engine do the rest. But I quickly discarded this idea.

First of all I don’t use real physics in my game. Character controller is fully kinematic and only use different types of RayCasts and CapsuleCasts to get information about surroundings. Also, 3D physics in Unity is non-deterministic, so I don’t really like it.

The second idea was to animate snake tail along the path. This approach would require extra work on level design part to setup every single tunnel. I wanted more flexible solution with minimum overhead.

So, I had to write my own snake tail logic.

Prototype on flat surface

Same as for Spider Legs I started with simple prototype on a flat surface. I wrote a script which has array of Transforms the act as tail segments. The very first element of the array is head and set the trajectory for all other segments to follow. It also allows to tweak linear speed, turning speed and distance between segments.

Snake Tail Prototype

It worked as expected. I didn’t set goal to create Ultimate Ultra-Realistic Snake Controller so I decided to keep this implementation even though it has some limitations, but I could live with them.

The script for this prototype can be found here if you are interested how the code looks like.

Testing with real snake model

As soon as I made it work I attached this script to my snake model to see if it works with bones and to test mesh deformation without spiral crawling animation at the moment:

Snake Deformation Test

And then with crawling animation on top of it:

Snake Procedural Crawling

Adapting to gameplay

After that I had to work a bit more to make it work with dashing in 8 directions and to prevent snake twisting incorrectly inside the tunnels.

The final version looks like this (still no transition):

Snake Procedural Animation in Tunnel

Character animation

For this ability character animation is quite simple.

The main transition will be implemented using different particle FXs and shaders. The snake won’t instantly appear as a whole but will crawl out of a portal created at character’s position. The part of the snake that is still inside the portal will be cut by shader. The same principle will be applied for the transition from the snake back to character form (the snake will crawl into the portal).

Main character’s animation in slomo:

Snake Transition Character Animation

Tentacle

In King, Witch and Dragon the main character can use grappling hook to pull himself towards the walls or to pull enemies to his sword. But instead of throwing actual hook he is stretching long tentacle (remember, all abilities received from Witch).

Tentacle Concept

Procedural generation of everything

If for previous abilities I used procedural animation, for the tentacle I decided to procedurally generate everything!

When this ability is activated the game in real-time starts doing the following:

  • generate tentacle mesh with suckers
  • assign UV-coordinates to the vertices
  • apply material with texture
  • calculate surface normals
  • bend, twist and offset tentacle according to specified parameters

Manually set vertex coordinates, UV, array of triangles and everything else is very tedious process. But if you are interested to dig deeper in procedural generation in Unity I highly recommend start with this article on Catlike Coding and also watch videos on Board To Bits YouTube channel

What I achieved

At the beginning I made a tentacle that gets list of parameters and applies it to the whole mesh:

Procedural Tentacle

On the GIF you can see how it can change in real-time thickness, twist amount and offset from the central axis. I can also specify size, quantity and distance between suckers.

Even with these basic parameter the tentacle looks decent, but I decided to push forward.

If you take a look at the concept above you will see that the tentacle wraps around character’s arm a couple times and then twists with much bigger amplitude. This effect cannot be achieved using equal (or linear) distribution of the values across the tentacle. I added ability to use Unity’s Animation Curves in the inspector to control non-linear values distribution across the tentacle:

Non-linear distribution

With this tool it is possible to:

  • make more tight turns at the beginning and wide turns closer to the tip of the tentacle
  • smaller offset at the beginning (wrap around character’s arm) and bigger offset in the middle and closer to the tip
  • keep constant thickness and shrink it at the very end
  • make different profiles for stretching forward, pulling towards and returning back

This is how it looks on static character:

Tentacle with Static Character

Character animation

For the main character I made an animation of stretching arm in the direction of tentacle.

I started with simple IK chain:

Arm Stretching IK

As you can see there are several problems. The shoulder and torso doesn’t react to this movement. In reality we cannot rise our arm without moving the shoulder, our skeleton doesn’t allow us to do so. Also, when aiming down the arm clips through the character’s leg.

To solve these problems I made 3 additive animations (aiming up, forward and down) and started to mix them depends on the aiming angle:

Arm Stretching Additive

Look direction

I also made character to look in the direction of player input. It feels especially good when you play with gamepad and character turns his head following left stick on the gamepad.

Look At

This is very small detail but it gives feeling of responsiveness.

Showcase

I create a test level and recorded first trailer to showcase all abilities in action:


To support project please add King, Witch and Dragon to your Steam Wishlist. To get more updates and materials about the project follow me on Twitter and Instagram.