Unity: Making Stretchy-Squashy Rotations with Dot Products and A Blend Tree

Unity: Making Stretchy-Squashy Rotations with Dot Products and A Blend Tree

[ insert header graphic ]

    This is a quick rundown on how BomBo's (the main character in The Lullaby of Life) organic rotation system was created. This solution was created on Unity and requires basic knowledge of
    This solution is straightforward and general enough to apply on similar and not-so-similar cases.

The Problem

    One of the early requirements in the animation system for BomBo was making its rotation to organically follow the character's movement. Beyond a simple change in orientation: how to add a dynamic "twist/stretch" to make the character more alive?

The Insight

The twist in the character is directly proportional to the difference between the character's orientation and the input direction.
    This is: the more perpendicular the character (its transform.up vector) is to the input vector, the more its body twists in the input direction. Similarly: the more the character's transform.up aligns with the input vector, the more the character stretches -or squashes, when the vectors are opposite.

    This concept can be translated into two dot products:
  • transform.up · inputVector is the overlap between the character's direction and the input direction (0 if stationary; 1 when identical, -1 when opposite).
  • transform.right · inputVector is the overlap between the character's "right side" and the input direction (0 when not turning; 1 when turning right; -1 when turning left).
[ diagram showing the way the vectors' dot products interact]

    These values will be changing dynamically as the character rotates -which is precisely what we need.

The Implementation

    We start creating a script to calculate these two dot products (we will call dotForward and dotRight) and setting them up to be used as output values.

[ code snippet ]

    Then, using the character model, we create several single-frame animation clips, storing the "extreme poses" for all of the character's rotation cases.

[ screenshot / collage of different poses ]

    Finally, we put these two together into an Animator's 2D Blend Tree:
  • In an Animator Controller, we create two float parameters to receive our dot products.
[ screenshot of animator's parameters ]
  • We create a Blend Tree state, set it up as a 2D Cartesian Blend Tree, and assign dotRight and dotForward respectively as horizontal and vertical axes.
  • We place our character poses in their corresponding coordinate.
[ screenshot of animator's final setup ]

As the final touch, we add a new Animator Layer and place there the basic non-rotation states for the character (in the simplest form, an Idle, and an Interact states), set as "Additive", to overlay with the twisting positions.

And, like this, the character is twisting and aligning with its movement direction.

Comments