2d BB-8

The coolest new character in Star Wars Episode VII: The Force Awakens is BB-8, the droid that rolls on his spherical body with his head bopping along on top. It’s a great design and fun a character. Here’s how to achieve a 2D BB-8 in Unity.

The Basics

The HeadMovement script is the part that is special to BB-8’s movement, and that is detailed below. Everything else is standard Unity basics, so to keep this tutorial short I won’t cover that. I’ve included a link to the completed project at the bottom, so you can look at the full code in there if you wish.

The Character

The Body

BB-8’s body is a circular sprite with a circle collider and rigidbody2d. I’ve tweaked its physics properties to get the right feel. We also have a simple player controller script that checks for left, right, and jump input.

The Head

The head itself is just a sprite and a script. The script checks the head’s position relative to the body and adjusts it to point in the right direction and ‘correct’ itself upright. Lerping is used to give the self-correcting a tangible, smooth feel.

Here’s the script code:

using UnityEngine;
using System.Collections;

public class HeadMovement : MonoBehaviour {
   [SerializeField]
   private Transform _bodyTransform;
   private Transform _headTransform;
   [SerializeField] private float distanceFromBody = 0.65f;
   private SpriteRenderer _headSprite;
   private float _lastPosX;

   void Start()
   {
      _headTransform = GetComponen<Transform>();
      _headSprite = GetComponent<SpriteRenderer>();
      _lastPosX = _bodyTransform.position.x;
   }

   void FixedUpdate()
   {
      _headTransform.position = Vector2.Lerp(_headTransform.position, new Vector2(_bodyTransform.position.x, _bodyTransform.position.y + distanceFromBody), 0.35f);
     _headTransform.rotation =     Quaternion.Lerp(_headTransform.rotation, Quaternion.Euler(0, 0, 0), 0.35f);
     if ((_bodyTransform.position.x - _lastPosX) > 0.01f)
     {
       _headSprite.flipX = true;
     }
     else if ((_bodyTransform.position.x - _lastPosX) < -0.01f)
     {
        _headSprite.flipX = false;
     }
     _lastPosX = _bodyTransform.position.x;
   }
}

The idea behind the script is to maintain the correct angle and position. In FixedUpdate(), we do three things:

  1. Lerp the head’s position back to the point directly above the ball’s centre
  2. Lerp the head’s angle back to zero (upright)
  3. Make sure BB-8 is looking in the direction of the body’s movement.

That’s It

That’s all there is to it. You can tweak some of the settings to adjust the movement (and you can easily create better graphics than mine). If you find a way to improve this please share your ideas in the comments.

Leave a Comment