Creating Your Own Hand Prefabs

You can make your own hand prefabs similar to those include in the core asset package. This allows you to create your own graphics and customized behaviors based on the existing scripts.

Discrete Hand Prefabs

“Discrete” hands mean that each part of the hand is a separate game object with its own position and orientation. In the core asset package, the robot hands and the minimal hands are examples of discrete hands. Creating the prefabs is a bit of an involved process. The following discussion walks through the steps using Unity built-in primitive objects (cylinders and spheres).

https://di4564baj7skl.cloudfront.net/documentation/v2/images/unity/Unity_KnobbyHand.jpg

A prefab hand created using Unity primitives

A couple of points before we get started:

  • Each graphics primitive is placed inside an empty game object. The hand and finger scripts update the transform of this empty game object. The local transform of the primitive object itself orients and sizes the object relative to this empty parent.
  • Remove any colliders from the parts of the graphics hand. Otherwise, these will make the colliders in the RigidHand bounce around.
  • Generally, you don’t need parts for both the joints and the bones. They aren’t really independent of each other, so you can use which ever makes more sense for your hand model. In this tutorial, we will add both just to show how it is done.
  • Similarly, your model might not need both metacarpal bones and a palm. The metacarpal bones are enclosed in the palm and don’t move independently. This tutorial includes both.
  • Use real-world sizes for the hand model. The hand and finger scripts do not resize the parts individually. The overall scale is set by scale assigned to the HandController object, but this also affects the range of motion of the hand. The size of the hand at 1:1 should be that of a typical human hand (and remember that the standard unit in Unity is 1 meter).
  • Very abstract and symmetrical designs, like the one created in this tutorial, can use the same prefab for both right and left hands. Most models, however, will need a different prefab for each hand in order to adjust the local transforms of the hand components properly.

First, we will create a prefab for the finger and then use that in constructing the hand prefab. To get started, create a new Unity project and import the Leap Motion asset package.

Create the Finger Prefab

To create the finger prefab:

  1. Create a scene for the construction.

  2. Add an empty game object, named KnobbyFinger, to the scene.

  3. Create the bones:

    1. Add an empty game object to KnobbyFinger. Name it Metacarpal.

    2. Add a Cylinder to Metacarpal, name it Tube. When creating your own hands, replace the cylinder with your own graphics object or objects.

    3. Remove the collider component — otherwise the RigidHand colliders bounce off it.

    4. Set the x rotation to 90.

      It helps to be in top view to align the graphics object to the finger. In top view, the direction from base of finger (or hand) toward the tip is toward the top of the screen (+z). The x axis corresponds to the left/right direction (+x is right). The Unity cylinder primitive is in the wrong orientation. Rotating it 90 degrees aligns it with the finger axis. This rotation has to be done on the Tube transform since the Metacarpal transform is controlled by the finger script. Your own graphics objects might need a different rotation.

    5. Set both the Tube x and z scale to .003 (3 millimeters). This hand created in this tutorial intentionally uses extra-skinny bones. Real fingers are fatter.

    6. Set the Tube y scale to .034 (34mm). The y scale value determines length of finger segment.

      The sizes must use real-world hand sizes, converted into meters. The length (y scale) is half the target length of 68mm because the primitive cylinder is 2 units tall. Thus we have to scale down by an additional 50%. Note that these numbers aren’t magic. Feel free to experiment.

    7. Duplicate Metacarpal, name it Proximal, and set the y scale of its Tube to .02.

    8. Duplicate Metacarpal again, name it Intermediate, and set the y scale of its Tube to .01.

    9. Duplicate Metacarpal again, name it Distal, and set the y scale of its Tube to .007.

      All these bones must be children of the KnobbyFinger object.

  4. Create the Joints:

    Remember, you don’t necessarily need both bones and joints.

    1. Add an empty game object to KnobbyFinger. Name it MetacarpophalangealJoint.
    2. Add a Sphere primitive to the joint. Name it Knob.
    3. Remove the collider component from Knob.
    4. Set all the scale values of Knob to .01 (1cm).
    5. Duplicate MetacarpophalangealJoint and rename it ProximalinterphalangealJoint.
    6. Duplicate MetacarpophalangealJoint again and rename it DistalinterphalangealJoint.
  5. Arrange the bones and joints into a line. This arrangement is for show in the editor view only, but helps identify the parts when you need to make adjustments.

    https://di4564baj7skl.cloudfront.net/documentation/v2/images/unity/Unity_PrefabFinger.jpg

    Very Important: In this case, only change the transforms of the bone and joint game objects. Never the change the knobs and tubes when arranging the finger. Change the tube or knob transforms only to rotate the graphics objects or arrange multiple components of the same bone relative to each other. Be careful when selecting the bones and joints. If you click an object in the Scene view, Unity will select the Tube or Knob object, not the parent bone or joint.

  6. Add the SkeletalFinger script component to the KnobbyFinger object

  7. Drag each of the bones and joints you just created to corresponding the bone and joint slots in the script.

    The bones and joints must be in the following slots in the SkeletalFinger Bones and Joints arrays:

    Bones:

    • 0 - Metacarpal
    • 1 - Proximal
    • 2 - Intermediate
    • 3 - Distal

    Joints:

    • 0 - MetacarpohalangealJoint
    • 1 - ProximalinterphalangealJoint
    • 2 - DistalphalangealJoint
  8. Make the KnobbyFinger into a prefab by dragging it into the Asset folder from the Hierarchy panel.

Create the Hand Prefab

To create the hand prefab (after you have created the finger prefab):

  1. Create an empty game object. Name it KnobbyHand.

  2. Add the SkeletalHand script component to KnobbyHand.

  3. Drag 5 KnobyFinger prefabs into the hand. Name them Thumb, Index, Middle, Ring, and Pinky.

  4. For each finger, set the Finger type in the SkeletalFinger script component to the matching type.

  5. Drag the fingers to their correct slot in the SkeletalHand script component on KnobbyHand.

    Finger element order:

    • 0 - Thumb
    • 1 - Index
    • 2 - Middle
    • 3 - Ring
    • 4 - Pinky
  6. The Thumb is special in that it doesn’t have a real Metacarpal. Edit Thumb and remove the bone from element 0 in the bone array (leave as None). Delete the Metacarpal game object child of the thumb object in KnobbyHand.

  7. Add the palm:

    You can leave the slots for palm, wrist and forearm blank (None) if you don’t have graphics for them. The palm is also represented by RigidHand, so if you don’t use a palm, you might also want to modify a copy of RigidHand to remove the rigid body and collider for the palm.

    1. Add an empty game object to KnobbyHand. Name it Palm.
    2. Add a Cylinder primitive to Palm. Name it Disc.
    3. Remove the Collider component.
    4. Set the Disc transform scale to (.085, .0015, .085). (Again, these numbers aren’t magic, feel free to experiment).
    5. Drag Palm to the Palm slot in the SkeletalHand script.
  8. Add the wrist:

    1. Add an empty game object to KnobbyHand. Name it Wrist.
    2. Add a Sphere primitive to Wrist. Name it Ball.
    3. Remove the Collider.
    4. Set the Ball transform scale to (.03, .03, .03).
    5. Drag Wrist to the WristJoint slot in the SkeletalHand script.
  9. Add the arm:

    1. Add an empty game object to KnobbyHand. Name it Arm.
    2. Add a Cylinder primitive to Arm. Name it Rod.
    3. Remove the Collider.
    4. Set the Rod transform x rotation to 90.
    5. Set the Rod transform scale to (.02, .12, .02).
    6. Drag Arm to the Forearm slot in the SkeletalHand script.
  10. Arrange the parts of the hand as desired. This is only for aesthetics, the positions are overwritten at runtime. Again, only change the transforms that are direct children of the hand, not those of any of the graphics primitives.

    https://di4564baj7skl.cloudfront.net/documentation/v2/images/unity/Unity_PrefabHand.jpg
  11. Drag the KnobbyHand to the Asset folder to create a prefab.

The KnobbyHand hierarchy should look like the following:

https://di4564baj7skl.cloudfront.net/documentation/v2/images/unity/Unity_KnobbyHand_Heirarchy.png

Test Your new Hand

To test the hands:

  1. Add a HandController prefab to the scene so that it’s interaction area is in the camera’s field of view.
  2. In the Hand Controller Script component, uncheck Separate Left/Right.
  3. Drag KnobbyHand to the HandGraphics Model slot.
  4. Make sure that RigidHand is in the Hand Physics Model slot (drag in the prefab, if necessary). You can leave the Tool Model slot empty.
  5. Play the level and observe the hands.

Creating hands is a complicated process and there is a lot that can go wrong. Use the hierarchy view to find the parts of the “live” hand, if one isn’t in the right place. You can pause the game to freeze the live hand so that you can inspect its properties more closely.

If the RigidHand components, visible in scene view, are jittery or bouncing, make sure that you removed all the collider components from the graphics hand parts.

If fingers overlap and move under control of a single real finger, check the finger type settings in the SkeletalFinger script components of the fingers.

If the hand parts are all munged together in a big blob, the primitive scale values are set too large. Remember that in Unity, 1 is 1 meter. A typical hand width is 8.5 centimeters, or .085 in the Unity transform scale value. To make hands larger in a game, scale up the HandController object.