# Overview

An overview of the asset's provided packages and key features.

The Hand Tracking Unity plugin is an asset designed to track hands and finger joints accurately. Using color data, it detects hands in images, identifies key joint positions, and supports both 2D and 3D joint positioning.

## Available packages

There are various options to choose from, depending on the platform you are developing for.&#x20;

Every package comes with support for the Unity Editor, simplifying your development and testing processes.

{% hint style="info" %}
All packages support Unity Editor on Mac and Windows.
{% endhint %}

<table><thead><tr><th>Package</th><th width="218">Runtime</th><th>Download</th></tr></thead><tbody><tr><td><strong>iOS</strong></td><td>iOS, iPadOS</td><td><a href="https://u3d.as/3e6S"><em>Download for iOS</em></a></td></tr><tr><td><strong>Android</strong></td><td>Android</td><td><a href="https://u3d.as/3e6T"><em>Download for Android</em></a></td></tr><tr><td><strong>iOS + Android</strong></td><td>iOS, iPadOS, Android</td><td><a href="https://u3d.as/3hPh"><em>Download for iOS + Android</em></a></td></tr><tr><td><strong>macOS</strong></td><td>macOS</td><td><a href="https://u3d.as/3hP3"><em>Download for macOS</em></a></td></tr><tr><td><strong>Windows</strong></td><td>Windows</td><td><a href="https://u3d.as/3hP2"><em>Download for Windows</em></a></td></tr><tr><td><strong>visionOS</strong></td><td>Apple Vision Pro</td><td><em>Coming soon</em></td></tr></tbody></table>

{% hint style="warning" %}
All packages, except visionOS, are compatible with Unity 2020 and later versions. However, packages including visionOS are compatible with Unity 2022 or later due to the lack of support in earlier Unity versions.
{% endhint %}

## Key Features

* **Precise Tracking**: Detects both 2D and 3D coordinates of each finger joint, ensuring accurate joint positioning in both the image plane and three-dimensional space.
* **Out-of-the-Box Visualization:** Provides ready-to-use visualization components and comprehensive examples, significantly reducing your development effort.
* **Application Versatility:** Supports all major platforms, enabling you to develop your application once and deploy it universally.

## Workflow

The Hand Tracking Unity plugin is the easiest way to add hand and finger tracking to your application.     &#x20;

You can detect hands and fingers in 3 easy steps:

1. Load a raw RGB-encoded byte array to a `Texture2D`. The byte array could be an image file, a video file (eg mp4 file) or a camera live feed.
2. Pass the `Texture2D` to a `HandTracker`. The `HandTracker` will detect the hands and fingers in the texture.
3. Access the detected hand's information. The detected `Hand` includes the following information:
   * Side: The side of the hand (Left or Right).
   * Confidence: The tracking confidence of the hand (0 to 1).
   * Thumb: The 2D and 3D positions for the CMC, MCP, IP and Tip thumb joints.
   * Index: The 2D and 3D positions for the MCP, PIP, DIP and Tip index joints.
   * Middle: The 2D and 3D positions for the MCP, PIP, DIP and Tip middle joints.
   * Ring: The 2D and 3D positions for the MCP, PIP, DIP and Tip ring joints.
   * Pinky: The 2D and 3D positions for the MCP, PIP, DIP and Tip pinky joints.
   * Palm: The 2D and 3D positions for the wrist, middle of the palm, thumb CMC, thumb MCP, index MCP, middle MCP, ring MCP and pinky MCP joints.


# System Requirements

Supported platforms & system specifications.

### Supported Platforms

The Hand Tracking Unity plugin supports the most popular development platforms both for desktop and mobile. You can also test your software directly in the Unity Editor before deploying.

{% hint style="info" %}
All packages support Unity Editor on Mac and Windows.
{% endhint %}

<table data-full-width="false"><thead><tr><th>Platform</th><th width="296">Runtime</th><th>Version</th></tr></thead><tbody><tr><td>Android</td><td>Android ARM64, ARM32, x86, x64</td><td>Android API Level 33 or higher</td></tr><tr><td>iOS</td><td>iOS, iPadOS, Mac Catalyst</td><td>iOS 14+</td></tr><tr><td>macOS</td><td>macOS M1, M2, M3, Intel</td><td>macOS Monterey 12+</td></tr><tr><td>visionOS</td><td>visionOS</td><td>visionOS 1.0+</td></tr><tr><td>Windows</td><td>Windows x64</td><td>Windows 10+</td></tr><tr><td><em>Unity Editor</em></td><td><em>Mac, Windows</em></td><td><em>Unity 2020+</em></td></tr></tbody></table>

These requirements ensure that the Hand Tracking Unity plugin runs smoothly across the various platforms for a wide range of devices.


# Installation

Instructions on how to install the Hand Tracking Unity Plugin to your project.

Download the [package](/#available-packages) that covers your needs from the Unity Asset Store.

Open Unity Hub.

Click the New Project button.

<figure><img src="/files/iMP2cUtNR6i3FIfUfKXM" alt=""><figcaption><p>New Project</p></figcaption></figure>

Type the Project name, select Location and Unity Cloud Organisation.

<figure><img src="/files/UnIA582qo4BxTsN0q4v0" alt=""><figcaption><p>Project Settings</p></figcaption></figure>

Right-click on the Assets Folder.

Select Import Package and then Custom Package.

<figure><img src="/files/06JbMZSMHALb1kOIElJk" alt=""><figcaption><p>Import Package</p></figcaption></figure>

Navigate to the folder containing the downloaded Unity package and select Open.

<figure><img src="/files/vlqeWoSyVaF43h0dJETA" alt=""><figcaption><p>Select Package to import</p></figcaption></figure>

Import all package contents.

<figure><img src="/files/Oz3YBqtct4qOlZIJYEJe" alt=""><figcaption><p>Import all contents</p></figcaption></figure>

By following these steps, you will be able to import the plugin into your project and incorporate hand tracking into your application.


# QuickStart

A QuickStart overview on how to detect hands and retrieve finger joint information.

Following the steps described in the [Workflow](/#workflow) section, here is how to detect hands and fingers in 3 easy steps:

## Step 1: Load image data

Load an image to a `Texture2D`. The image could be loaded from one of the following sources:

### :frame\_photo: Image file

*An image file is a PNG, JPG, WEBP, or BMP image.*

```csharp
// Create an empty Texture2D.
Texture2D texture = new Texture2D(0, 0);

// Load a file to a byte array.
string filename = "path/to/image";
byte[] rawData = System.IO.File.ReadAllBytes(filename);

// Load an byte array to the Texture2D.
texture.LoadImage(rawData);
```

### &#x20;:movie\_camera: Video file

*A video may by an MP4, AVI, MOV, WEBM, or WMV file.*

```csharp
[SerializeField] VideoPlayer _videoPlayer;

// Create a RenderTexture with Videoplayer frame data.
RenderTexture renderTexture = (RenderTexture)_videoPlayer.texture;
RenderTexture.active = renderTexture;

// Load image from RenderTexture to a Texture2D.
Texture2D texture = new Texture2D(0, 0);
texture.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
texture.Apply();
```

### :camera: Camera feed

*Computer webcams, external USB cameras, and phone rear/selfie cameras are supported.*

<pre class="language-csharp"><code class="lang-csharp">[SerializeField] private ImageView _image;
[SerializeField] private WebcamSource _webcam;

// Load the new frame to an ImageView.
_image.Load(_webcam);

<strong>// Load image from ImageView to a Texture2D.
</strong>Texture2D texture = _image.Texture;
</code></pre>

## Step 2: Detect hands

Pass the `Texture2D` from step 1 to a `HandTracker`. The `HandTracker` will detect the hands and fingers in the texture.

```csharp
// Create a handTracker.
HandTracker tracker = new HandTracker();

// Detect hands.
List<Hand> hands = tracker.Load(texture);
```

## Step 3: Access hand & finger data

Access the detected hand's information.&#x20;

```csharp
if (hands.Count > 0)
{
    // Get hand Side. 
    HandSide side = hands[0].Side;
    
    // Get hand Confidence. 
    float confidence = hands[0].Confidence;
    
    // Get Thumb finger.
    Thumb thumb = hands[0].Thumb;
    
    // Get Index finger.
    Index index = hands[0].Index;
    
    // Get Middle finger.
    Middle middle = hands[0].Middle;
    
    // Get Ring finger.
    Ring ring = hands[0].Ring;
    
    // Get Pinky finger.
    Pinky pinky = hands[0].Pinky;
    
    // Get Palm.
    Palm palm = hands[0].Palm;
    
    // Get Pinky MCP finger joint.
    FingerJoint pinkyMCP = pinky.MCP;
    
    // Get Pinky MCP joint 2D position.
    Vector2 screenPosition = pinkyMCP.Position2D;
    
    // Get Pinky MCP joint 3D position.
    Vector3 worldPosition = pinkyMCP.Position3D;
}
```

## Examples

For more detailed examples, check our dedicated Examples section:

{% content-ref url="/pages/VlkQs6eTkqRGi91POAQE" %}
[Detect hand and retrieve joints](/examples/detect-hand-and-retrieve-joints)
{% endcontent-ref %}

{% content-ref url="/pages/Vodof9URCBrb91OBVIRc" %}
[No Code: Detect and visualize hands from a Sprite](/examples/no-code-detect-and-visualize-hands-from-a-sprite)
{% endcontent-ref %}

{% content-ref url="/pages/oktrLMmh8gE7GLw6TV3l" %}
[Detect and visualize hands from a Sprite](/examples/detect-and-visualize-hands-from-a-sprite)
{% endcontent-ref %}

{% content-ref url="/pages/usuACFaZDgmx3x8yaoj2" %}
[Detect and visualize hands from a video](/examples/detect-and-visualize-hands-from-a-video)
{% endcontent-ref %}

{% content-ref url="/pages/7LHE6SC5dafNS2aRvC9A" %}
[Use webcam to detect and visualize hands (2D Canvas)](/examples/use-webcam-to-detect-and-visualize-hands-2d-canvas)
{% endcontent-ref %}

{% content-ref url="/pages/M2XXl0enlC05xE1xwHoS" %}
[Use webcam to detect and visualize hands (3D World space)](/examples/use-webcam-to-detect-and-visualize-hands-3d-world-space)
{% endcontent-ref %}


# Supported Joints

Explains the finger joints tracked in the Hand Tracking Unity plugin.

The Hand Tracking Unity plugin supports 22 different joints, as shown in the picture.

<div data-full-width="true"><figure><img src="/files/1Gu2pJRzb0T8Nzk71XTQ" alt=""><figcaption><p>Supported Joints</p></figcaption></figure></div>

Below you can find the joints grouped by area:

### Root

<table><thead><tr><th>Name</th><th>Description</th><th data-hidden>Index</th></tr></thead><tbody><tr><td>Root</td><td>The root of the hand (wrist).</td><td>0</td></tr></tbody></table>

### Thumb

<table data-full-width="false"><thead><tr><th>Name </th><th>Description</th><th data-hidden>Index</th></tr></thead><tbody><tr><td>Thumb CMC</td><td>The thumb carpometacarpal joint.</td><td>1</td></tr><tr><td>Thumb MCP</td><td>The thumb metacarpophalangeal joint.</td><td>2</td></tr><tr><td>Thumb IP</td><td>The thumb interphalangeal joint.</td><td>3</td></tr><tr><td>Thumb Tip</td><td>The thumb tip joint.</td><td>4</td></tr></tbody></table>

### Index Finger

<table><thead><tr><th>Name </th><th>Description</th><th data-hidden></th></tr></thead><tbody><tr><td>Index MCP</td><td>The index finger metacarpophalangeal joint.</td><td>5</td></tr><tr><td>Index PIP</td><td>The index finger proximal interphalangeal joint.</td><td>6</td></tr><tr><td>Index DIP</td><td>The index finger distal interphalangeal joint.</td><td>7</td></tr><tr><td>Index Tip</td><td>The index finger tip joint.</td><td>8</td></tr></tbody></table>

### Middle Finger

<table><thead><tr><th>Name </th><th>Description</th><th data-hidden></th></tr></thead><tbody><tr><td>Middle MCP</td><td>The middle finger metacarpophalangeal joint.</td><td>9</td></tr><tr><td>Middle PIP</td><td>The middle finger proximal interphalangeal joint.</td><td>10</td></tr><tr><td>Middle DIP</td><td>The middle finger distal interphalangeal joint.</td><td>11</td></tr><tr><td>Middle Tip</td><td>The middle finger tip joint.</td><td>12</td></tr></tbody></table>

### Ring Finger

<table><thead><tr><th>Name </th><th>Description</th><th data-hidden></th></tr></thead><tbody><tr><td>Ring MCP</td><td>The ring finger metacarpophalangeal joint.</td><td>13</td></tr><tr><td>Ring PIP</td><td>The ring finger proximal interphalangeal joint.</td><td>14</td></tr><tr><td>Ring DIP</td><td>The ring finger distal interphalangeal joint.</td><td>15</td></tr><tr><td>Ring Tip</td><td>The ring finger tip joint.</td><td>16</td></tr></tbody></table>

### Pinky

<table><thead><tr><th>Name </th><th>Description</th><th data-hidden>Index</th></tr></thead><tbody><tr><td>Pinky MCP</td><td>The pinky finger metacarpophalangeal joint.</td><td>17</td></tr><tr><td>Pinky PIP</td><td>The pinky finger proximal interphalangeal joint.</td><td>18</td></tr><tr><td>Pinky DIP</td><td>The pinky finger distal interphalangeal joint.</td><td>19</td></tr><tr><td>Pinky Tip</td><td>The pinky finger tip joint.</td><td>20</td></tr></tbody></table>

### Palm

<table><thead><tr><th>Name</th><th>Description</th><th data-hidden>Index</th></tr></thead><tbody><tr><td>Palm</td><td>The middle of the palm.</td><td>21</td></tr></tbody></table>


# Detect hand and retrieve joints

An example on how to detect hands and retrieve finger joint information.

This example demonstrates how to load  an image file into a `Texture2D`, implement hand tracking with the [HandTracker](/api-reference/handtracker),  and retrieve joint information of the detected index finger.

#### Step 1: Load the Image into Texture2D

1. Ensure you have your image file ready, preferably in a supported format such as PNG or JPEG.
2. Use the appropriate method (e.g., `Texture2D.LoadImage`) to load your image into a `Texture2D` object.

```csharp
// Create an empty Texture2D.
Texture2D texture = new Texture2D(0, 0);

// Load a file to a byte array.
string filename = "path/to/image";
byte[] rawData = System.IO.File.ReadAllBytes(filename);

// Load an byte array to the Texture2D.
texture.LoadImage(rawData);
```

#### Step 2: Create and Use a HandTracker

1. Instantiate a [HandTracker](/api-reference/handtracker) object in your application. The [HandTracker](/api-reference/handtracker) is responsible for detecting hands within the texture.
2. Pass the `Texture2D` object created in Step 1 to the [HandTracker](/api-reference/handtracker) for processing.
3. The [HandTracker](/api-reference/handtracker) will analyze the texture and detect any hands present in the image.

```csharp
// Create a handTracker.
HandTracker tracker = new HandTracker();

// Detect hands.
List<Hand> hands = tracker.Load(texture);
```

#### Step 3: Retrieve Index Finger Joint Information

1. Once a hand is detected in Step 2,  you can retrieve information on the detected hand, its fingers and their finger joints.
2. Specifically, get the hand side (left or right) and the index finger's information. The index includes, among other joints, the 2D and 3D positions of the index metacarpophalangeal joint as shown in this example.

```csharp
// If at least one hand is detected
if (hands.Count > 0)
{
    // Get hand side. 
    HandSide side = hands[0].Side;
    
    // Get index finger.
    Index index = hands[0].Index;
    
    // Get index MCP finger joint.
    FingerJoint indexMCP = index.MCP;
    
    // Get joint 2D position.
    Vector2 screenPosition = indexMCP.Position2D;
    
    // Get joint 3D position.
    Vector3 worldPosition = indexMCP.Position3D;
}
```

### Full example code

```csharp
string filename = "path/to/image";
byte[] rawData = System.IO.File.ReadAllBytes(filename);
Texture2D texture = new Texture2D(0, 0);
texture.LoadImage(rawData);

// Create a handTracker.
HandTracker tracker = new HandTracker();

// Find hands in an image.
List<Hand> hands = tracker.Load(texture);

// If at least one hand is detected
if (hands.Count > 0)
{
    // Get hand side. 
    HandSide side = hands[0].Side;
    // Get index finger.
    Index index = hands[0].Index;
    // Get index MCP finger joint.
    FingerJoint indexMCP = index.MCP;
    // Get joint 2D position.
    Vector2 screenPosition = indexMCP.Position2D;
    // Get joint 3D position.
    Vector3 worldPosition = indexMCP.Position3D;
}
```

By following these steps, you will be able to load an image, detect hands within it, and obtain detailed joint information for the index finger using a`Texture2D` and the [HandTracker](/api-reference/handtracker).


# No Code: Detect and visualize hands from a Sprite

An example on how to detect and visualize hands from a Sprite.

This example demonstrates how to detect and visualize fingers in an image sprite using an [ImageView](/ui-reference/imageview),  a [SpriteSource](/ui-reference/streamsource/spritesource), a [HandManager](/ui-reference/handmanager) and a [HandViewer](/ui-reference/handviewer). No code is needed for this example!

{% hint style="warning" %}
All Hand Tracking Unity plugin samples are no-code! You can find the code versions in the `Examples` section of this documentation.
{% endhint %}

{% hint style="info" %}
This is a walkthrough of the `LightBuzz_Hand_Tracking_Picture` Hand Tracking Unity plugin sample.&#x20;
{% endhint %}

#### Step 1: Create a Unity scene

Open the Unity Project you created in the [Installation](/hand-tracking-unity-plugin/installation) section.

Right-click on the `Assets` folder and select `Create > Scene`.

<figure><img src="/files/AWAZBZqNkgh8mdgwr3hv" alt=""><figcaption><p>Create new scene</p></figcaption></figure>

Type the scene's name. In this example, we'll use the name `PictureDemoNC`.

After the scene is created, right-click on the scene and select `GameObject > UI > Canvas`.

<figure><img src="/files/SOVl2RObo6YAMFPnsd5J" alt=""><figcaption><p>Add a Canvas</p></figcaption></figure>

#### Step 2: Add hand tracking prefabs

Navigate to the LightBuzz `Prefabs` folder at `Assets\LightBuzz Hand Tracking\Runtime\Prefabs`.

<figure><img src="/files/aLOxlnZxIBjwQFtfkzwZ" alt=""><figcaption><p>LightBuzz Prefabs</p></figcaption></figure>

For this example, drag and drop the [ImageView](/ui-reference/imageview), [SpriteSource](/ui-reference/streamsource/spritesource), [HandViewer](/ui-reference/handviewer) and [HandManager](/ui-reference/handmanager) prefabs into the Canvas.

<figure><img src="/files/EcALmttcB1gbOreRV2tg" alt=""><figcaption><p>Add prefabs</p></figcaption></figure>

Select the [SpriteSource](/ui-reference/streamsource/spritesource) prefab and connect the `Sprite` field to an image sprite. You can either use the demo image sprite `lightbuzz-hand-tracking.png` included in the `Assets/LightBuzz Hand Tracking/Runtime/Media` folder or create your own image sprite.

<figure><img src="/files/GlIOHE0ryaagjza8xtQD" alt=""><figcaption><p>Connect field to SpriteSource</p></figcaption></figure>

#### Step 3: Set render options

After connecting all the fields, navigate to the `Canvas` to set the render options.

Change the `Render Mode` to `Screen Space - Camera`.

<figure><img src="/files/8xapwQLfkO58oNi2gJhH" alt=""><figcaption><p>Change Render Mode</p></figcaption></figure>

Then, set the `Main Camera,` from the Scene tab, as the `Render Camera`.

<figure><img src="/files/FKcxZ5Eyq9JlM0GAFHZu" alt=""><figcaption><p>Select Render Camera</p></figcaption></figure>

When all the render options are set, the result should look like the following image.

<figure><img src="/files/bVxgPsw5dk4FXW0xcKXy" alt=""><figcaption><p>Render settings</p></figcaption></figure>

By following these steps, you will be able to detect and visualize fingers in an image sprite without a single line of code.


# Detect and visualize hands from a Sprite

An example on how to detect and visualize hands from a Sprite.

This example demonstrates how to load and display image sprites in a Unity scene with an [ImageView](/ui-reference/imageview), implement hand tracking with the [HandTracker](/api-reference/handtracker), and use the [HandManager](/ui-reference/handmanager) to render detected fingers on a 2D canvas.

{% hint style="info" %}
This is a code walkthrough of the `LightBuzz_Hand_Tracking_Picture` Hand Tracking Unity plugin sample. The plugin includes the no-code demo that has the same functionality.
{% endhint %}

#### Step 1: Create a Unity scene

Open the Unity Project you created in the [Installation](/hand-tracking-unity-plugin/installation) section.

Right-click on the `Assets` folder and select `Create > Scene`.

<figure><img src="/files/AWAZBZqNkgh8mdgwr3hv" alt=""><figcaption><p>Create new scene</p></figcaption></figure>

Type the scene's name. In this example, we'll use the name `PictureDemo`.

After the scene is created, right-click on the scene and select `GameObject > UI > Canvas`.

<figure><img src="/files/SOVl2RObo6YAMFPnsd5J" alt=""><figcaption><p>Add a Canvas</p></figcaption></figure>

Navigate to the LightBuzz `Prefabs` folder at `Assets\LightBuzz Hand Tracking\Runtime\Prefabs`.

<figure><img src="/files/aLOxlnZxIBjwQFtfkzwZ" alt=""><figcaption><p>LightBuzz Prefabs</p></figcaption></figure>

For this example, drag and drop the [ImageView](/ui-reference/imageview) and [HandManager](/ui-reference/handmanager) prefabs into the Canvas.

<figure><img src="/files/kiYmZTQAcNRrO6ybgFIw" alt=""><figcaption><p>Add prefabs</p></figcaption></figure>

Then, right-click on the `Hierarchy` pane and select `Create Empty`.&#x20;

<figure><img src="/files/tWKAoCSDw2MNbLtdn4Dg" alt=""><figcaption><p>Create empty component</p></figcaption></figure>

Give a name to the new component. In this example, we'll use the name `Demo`.

Then, go to the `Inspector` pane and select `Add Component`. In the search bar, type `new` and select the `New script` option.

<figure><img src="/files/aEWEKS46jXoNR0dQLnvd" alt=""><figcaption><p>Add script</p></figcaption></figure>

Type the script's name and select `Create and Add`. For this example, we'll use the name `PictureDemo`.

<figure><img src="/files/UdNUhfe2m21EVxOqjwMA" alt=""><figcaption><p>Create script</p></figcaption></figure>

#### Step 2: Initialize the visual components

Double-click on the newly created `MonoBehaviour` script and import the necessary namespaces.

```csharp
using LightBuzz.HandTracking;
using System.Collections.Generic;
using UnityEngine;
```

For this example, we'll need a `Sprite`to load an image, an [ImageView](/ui-reference/imageview) to draw its texture and a [HandManager](/ui-reference/handmanager) to visualize the detected hands.

```csharp
[SerializeField] private ImageView _image;
[SerializeField] private HandManager _handManager;
[SerializeField] private Sprite _sprite;
```

After adding the serialized fields, go to the Unity Editor to connect these fields with the `Demo` component.

At the `Inspector` pane, select the round button next to each `SerializeField`.

<figure><img src="/files/wbb9SQGCIMCPKlkEvOqr" alt=""><figcaption><p>Seriaze fileds</p></figcaption></figure>

Then, at the `Scene` tab, select the corresponding prefab. For example, for the `Image` field, select the `ImageView` prefab.

<figure><img src="/files/0jqp9uI7zQIPnTTMXJIa" alt=""><figcaption><p>Connect prefab</p></figcaption></figure>

The `Sprite` field should connect to an image sprite. You can either use the demo image sprite `lightbuzz-hand-tracking.png` included in the `Assets/LightBuzz Hand Tracking/Runtime/Media` folder or create your own image sprite.

When all fields are connected, the result should resemble the following image.

<figure><img src="/files/sLMtwNsRgYZ769zwynhx" alt=""><figcaption><p>Connected serialize fields</p></figcaption></figure>

Then, select the `HandManager` prefab, under the `Canvas`, and connect the `Image` field to the `ImageView` prefab.

<figure><img src="/files/J7W7y81Uo00EVQAPLrLA" alt=""><figcaption><p>Connect field to HandManager</p></figcaption></figure>

{% hint style="info" %}
Make sure the `Is 2D` option is selected to see the hand tracking detections in the 2D space. If the option is not checked, detections are displayed in the 3D world space.
{% endhint %}

After connecting all the fields, navigate to the `Canvas` to set the render options.

Change the `Render Mode` to `Screen Space - Camera`.

<figure><img src="/files/8xapwQLfkO58oNi2gJhH" alt=""><figcaption><p>Change Render Mode</p></figcaption></figure>

Then, set the `Main Camera,` from the Scene tab, as the `Render Camera`.

<figure><img src="/files/FKcxZ5Eyq9JlM0GAFHZu" alt=""><figcaption><p>Select Render Camera</p></figcaption></figure>

When all the render options are set, the result should look like the following image.

<figure><img src="/files/bVxgPsw5dk4FXW0xcKXy" alt=""><figcaption><p>Render settings</p></figcaption></figure>

Finally, return to the script and instantiate a [HandTracker](/api-reference/handtracker) to detect hands.

```csharp
HandTracker _handTracker = new HandTracker();
```

#### Step 3: Load the image

Create a `Texture2D` object with the `Sprite`'s texture.

```csharp
Texture2D texture = _sprite.texture;
```

Load the `Texture2D` object onto the [ImageView](/ui-reference/imageview) to show the image.

```csharp
_image.Load(texture);
```

#### Step 4: Detect hands

Pass the texture created in Step 3 to the [HandTracker](/api-reference/handtracker) for processing.

```csharp
List<Hand> hands = _handTracker.Load(_image.Texture);
```

The [HandTracker](/api-reference/handtracker) will analyze the texture and detect any hands present in the image.

#### Step 5: Visualize the hands

To display the detected hands on a 2D canvas, simply pass the detections to the [HandManager](/ui-reference/handmanager).  It will manage the rendering and updates required to accurately depict the hands on the canvas based on the detection data provided.

```csharp
_handManager.Load(hands);
```

{% hint style="info" %}
Steps 3 through 5 are incorporated into the `Start()` method.
{% endhint %}

#### Step 6: Release the resources

Dispose of the [HandTracker](/api-reference/handtracker) object to ensure that all associated resources are released.

```csharp
_handTracker.Dispose();
```

{% hint style="info" %}
In this example, the resources are released in the `OnDestroy()` method. Alternatively, you could do that with the click of a button or in the `OnApplicationQuit()` method.
{% endhint %}

### Full example code

Here is the full example code that has the same functionality as the Hand Tracking Unity plugin  `LightBuzz_Hand_Tracking_Picture` sample.

```csharp
using LightBuzz.HandTracking;
using System.Collections.Generic;
using UnityEngine;

public class PictureDemo : MonoBehaviour
{
    [SerializeField] private ImageView _image;
    [SerializeField] private HandManager _handManager;
    [SerializeField] private Sprite _sprite;

    private readonly HandTracker _handTracker = new HandTracker();

    private void Start()
    {
        Texture2D texture = _sprite.texture;

        _image.Load(texture);

        List<Hand> hands = _handTracker.Load(_image.Texture);
        
        _handManager.Load(hands);
    }

    private void OnDestroy()
    {
        _handTracker.Dispose();
    }
}
```

By following these steps, you will be able to load a `Sprite` into your application, detect hands, and finally, render these detections on a 2D canvas.


# Detect and visualize hands from a video

An example on how to get video feed, detect and visualize hands in a 2D canvas.

This example demonstrates how to load and display a video in a Unity scene with a [VideoSource](/ui-reference/streamsource/videosource) and an [ImageView](/ui-reference/imageview), implement hand tracking with the [HandTracker](/api-reference/handtracker), and use the [HandManager](/ui-reference/handmanager) to render detected fingers on a 2D canvas.

{% hint style="info" %}
This is a code walkthrough of the `LightBuzz_Hand_Tracking_Video` Hand Tracking Unity plugin sample. The plugin includes the no-code demo that has the same functionality.
{% endhint %}

#### Step 1: Create a Unity scene

Open the Unity Project you created in the [Installation](/hand-tracking-unity-plugin/installation) section.

Right-click on the `Assets` folder and select `Create > Scene`.

<figure><img src="/files/AWAZBZqNkgh8mdgwr3hv" alt=""><figcaption><p>Create new scene</p></figcaption></figure>

Type the scene's name. In this example, we'll use the name `VideoDemo`.

After the scene is created, right-click on the scene and select `GameObject > UI > Canvas`.

<figure><img src="/files/SOVl2RObo6YAMFPnsd5J" alt=""><figcaption><p>Add a Canvas</p></figcaption></figure>

Navigate to the LightBuzz `Prefabs` folder at `Assets\LightBuzz Hand Tracking\Runtime\Prefabs`.

<figure><img src="/files/aLOxlnZxIBjwQFtfkzwZ" alt=""><figcaption><p>LightBuzz Prefabs</p></figcaption></figure>

For this example, drag and drop the [ImageView](/ui-reference/imageview), [VideoSource](/ui-reference/streamsource/videosource) and [HandManager](/ui-reference/handmanager) prefabs into the Canvas.

<figure><img src="/files/w1uyYtGbyf6lRt6pkKfE" alt=""><figcaption><p>Add prefabs</p></figcaption></figure>

Then, right-click on the `Hierarchy` pane and select `Create Empty`.&#x20;

<figure><img src="/files/tWKAoCSDw2MNbLtdn4Dg" alt=""><figcaption><p>Create empty component</p></figcaption></figure>

Give a name to the new component. In this example, we'll use the name `Demo`.

Then, go to the `Inspector` pane and select `Add Component`. In the search bar, type `new` and select the `New script` option.

<figure><img src="/files/aEWEKS46jXoNR0dQLnvd" alt=""><figcaption><p>Add script</p></figcaption></figure>

Type the script's name and select `Create and Add`. For this example, we'll use the name `VideoDemo`.

<figure><img src="/files/zJM0toCAYIptsc9LZEBp" alt=""><figcaption><p>Create script</p></figcaption></figure>

#### Step 2: Initialize the visual components

Double-click on the newly created `MonoBehaviour` script and import the necessary namespaces.

```csharp
using LightBuzz.HandTracking;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Video;
```

For this example, we'll need a `VideoPlayer` to get the video frames, an [ImageView](/ui-reference/imageview) to draw image texture and a [HandManager](/ui-reference/handmanager) to visualize the detected hands.

```csharp
[SerializeField] private ImageView _image;
[SerializeField] private HandManager _handManager;
[SerializeField] VideoPlayer _videoPlayer;
```

Add a `Texture2D` object to load the video frames.

```csharp
private Texture2D _texture;
```

After adding the serialized fields, go to the Unity Editor to connect these fields with the `Demo` component.

At the `Inspector` pane, select the round button next to each `SerializeField`.

<figure><img src="/files/lt4X63LB362hxQnNwyPU" alt=""><figcaption><p>Seriaze fileds</p></figcaption></figure>

Then, at the `Scene` tab, select the corresponding prefab. For example, for the `Image` field, select the `ImageView` prefab.

<figure><img src="/files/0jqp9uI7zQIPnTTMXJIa" alt=""><figcaption><p>Connect prefab</p></figcaption></figure>

When all fields are connected, the result should resemble the following image.

<figure><img src="/files/HQdcZHi3nuYq4wblTYVI" alt=""><figcaption><p>Connected serialize fields</p></figcaption></figure>

Then, select the `HandManager` prefab, under the `Canvas`, and connect the `Image` field to the `ImageView` prefab.

<figure><img src="/files/J7W7y81Uo00EVQAPLrLA" alt=""><figcaption><p>Connect field to HandManager</p></figcaption></figure>

{% hint style="info" %}
Make sure the `Is 2D` option is selected to see the hand tracking detections in the 2D space. If the option is not checked, detections are displayed in the 3D world space.
{% endhint %}

Then, select the `VideoSource` prefab, under the `Canvas,` and connect the `Video Clip` field to a video source. You can either use the demo video `lightbuzz-hand-tracking.mp4` included in the `Assets/LightBuzz Hand Tracking/Runtime/Media` or create your own video source.

<figure><img src="/files/EPZhswY0XITRnC3ScNNC" alt=""><figcaption></figcaption></figure>

After connecting all the fields, navigate to the `Canvas` to set the render options.

Change the `Render Mode` to `Screen Space - Camera`.

<figure><img src="/files/8xapwQLfkO58oNi2gJhH" alt=""><figcaption><p>Change Render Mode</p></figcaption></figure>

Then, set the `Main Camera,` from the Scene tab, as the `Render Camera`.

<figure><img src="/files/FKcxZ5Eyq9JlM0GAFHZu" alt=""><figcaption><p>Select Render Camera</p></figcaption></figure>

When all the render options are set, the result should look like the following image.

<figure><img src="/files/bVxgPsw5dk4FXW0xcKXy" alt=""><figcaption><p>Render settings</p></figcaption></figure>

Finally, return to the script and instantiate a [HandTracker](/api-reference/handtracker) to detect hands.

```csharp
HandTracker _handTracker = new HandTracker();
```

#### Step 3: Register handler methods to VideoPlayer events

Enable the `frameReady` events. Any registered delegates with `VideoPlayer.frameReady` will be invoked when a frame is ready to be drawn.

```csharp
 _videoPlayer.sendFrameReadyEvents = true;
```

Register for the `VideoPlayer.prepareCompleted` event with the `VideoPrepared` event handler method.

<pre class="language-csharp"><code class="lang-csharp"><strong>_videoPlayer.prepareCompleted += VideoPrepared;
</strong></code></pre>

Register for the `VideoPlayer.frameReady` event with the `VideoFrameReady` event handler method.&#x20;

```csharp
_videoPlayer.frameReady += VideoFrameReady;
```

Initiate playback engine preparation. After this is done, video frames can be received immediately.

<pre class="language-csharp"><code class="lang-csharp"><strong>_videoPlayer.Prepare();
</strong></code></pre>

{% hint style="info" %}
In this example, the `VideoPlayer` event handler methods are registered in the `Start()` method.
{% endhint %}

#### Step 4: Implement the VideoPrepared handler

Create the `Texture2D` according to the `VideoPlayer` resolution.

```
_texture = new Texture2D
    (
        (int)source.width,
        (int)source.height,
        TextureFormat.RGB24,
        false
    );
```

Start playback.

```csharp
_videoPlayer.Play();
```

{% hint style="info" %}
In this example, the prepare and playback functionality is implemented in the `VideoPrepared` event handler method.
{% endhint %}

#### Step 5: Implement the VideoFrameReadyhandler

Create a `RenderTexture` with the `VideoPlayer` frame data.

```csharp
RenderTexture renderTexture = (RenderTexture)_videoPlayer.texture;
RenderTexture.active = renderTexture;

_texture.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
_texture.Apply();
```

Load the texture onto the [ImageView](/ui-reference/imageview) to show the video feed.

```csharp
_image.Load(_texture);
```

Pass the `texture` to the [HandTracker](/api-reference/handtracker) for processing.

```csharp
List<Hand> hands = _handTracker.Load(_texture);
```

The [HandTracker](/api-reference/handtracker) will analyze the texture and detect any hands present in the image.

Pass the detections to the [HandManager](/ui-reference/handmanager).  The [HandManager](/ui-reference/handmanager) will manage the rendering and updates required to depict the detected hands.

```csharp
_handManager.Load(hands);
```

{% hint style="info" %}
In this example, all the hand-tracking functionality is implemented in the `VideoFrameReady` event handler method.
{% endhint %}

#### Step 6: Release the resources

Unsubscribe the `VideoPrepared` event handler method from the `VideoPlayer.prepareCompleted` event.

```csharp
_videoPlayer.prepareCompleted -= VideoPrepared;
```

Unsubscribe the `VideoFrameReady` event handler method from the `VideoPlayer.frameReady` event.

```csharp
_videoPlayer.frameReady -= VideoFrameReady;
```

Dispose of the [HandTracker](/api-reference/handtracker) object to ensure that all associated resources are released.

```csharp
_handTracker.Dispose();
```

Destroy the `Texture2D` object created in Step 2.

```csharp
Destroy(_texture);
```

{% hint style="info" %}
In this example, the resources are released in the `OnDestroy()` method. Alternatively, you could do that in the `OnApplicationQuit()` method.
{% endhint %}

### Full example code

Here is the full example code that has the same functionality as the Hand Tracking Unity plugin `LightBuzz_Hand_Tracking_Video` sample.

```csharp
using LightBuzz.HandTracking;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Video;

public class VideoDemo : MonoBehaviour
{
    [SerializeField] private ImageView _image;
    [SerializeField] private HandManager _handManager;
    [SerializeField] VideoPlayer _videoPlayer;

    private Texture2D _texture;

    private readonly HandTracker _handTracker = new HandTracker();

    private void Start()
    {
        // Enable the frameReady events.
        _videoPlayer.sendFrameReadyEvents = true;
    
        // Register the VideoPrepared handler method.
        _videoPlayer.prepareCompleted += VideoPrepared;
    
        // Register the VideoFrameReady handler method.
        _videoPlayer.frameReady += VideoFrameReady;
    
        // Initiate playback engine preparation.
        _videoPlayer.Prepare();
    }

    private void OnDestroy()
    {
        // Remove the VideoPrepared handler method.
        _videoPlayer.prepareCompleted -= VideoPrepared;
      
        // Unsubscribe the VideoFrameReady handler method.
        _videoPlayer.frameReady -= VideoFrameReady;
      
        // Dispose of the HandTracker.
        _handTracker.Dispose();
      
        // Destroy the texture.
        Destroy(_texture);
    }

    private void VideoPrepared(VideoPlayer source)
    {
        // Assign the VideoPlayer data to texture.
        _texture = new Texture2D((int)source.width, (int)source.height, TextureFormat.RGB24, false);
    
        // Start playback. 
        _videoPlayer.Play();
    }

    private void VideoFrameReady(VideoPlayer source, long frameIdx)
    {
        // Create a RenderTexture with Videoplayer frame data.
        RenderTexture renderTexture = (RenderTexture)_videoPlayer.texture;
        RenderTexture.active = renderTexture;

        _texture.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
        _texture.Apply();

        // Draw the camera texture.
        _image.Load(_texture);

        // Detect hands in the texture.
        List<Hand> hands = _handTracker.Load(_texture);

        // Visualize the hands on a Canvas.
        _handManager.Load(hands);
    }
}
```

By following these steps, you will be able to load the video feed into your application, detect hands, and finally, render these detections on a 2D canvas.


# Use webcam to detect and visualize hands (2D Canvas)

An example on how to get camera feed, detect and visualize hands in real time in a 2D canvas.

This example demonstrates how to load and display camera feed in a Unity scene with a [WebcamSource](/ui-reference/streamsource/webcamsource) and an [ImageView](/ui-reference/imageview), implement hand tracking with the [HandTracker](/api-reference/handtracker), and use the [HandManager](/ui-reference/handmanager) to render detected fingers on a 2D canvas.

{% hint style="info" %}
This is a code walkthrough of the `LightBuzz_Hand_Tracking_2D` Hand Tracking Unity plugin sample. The plugin includes the no-code demo that has the same functionality.
{% endhint %}

#### Step 1: Create a Unity scene

Open the Unity Project you created in the [Installation](/hand-tracking-unity-plugin/installation) section.

Right-click on the `Assets` folder and select `Create > Scene`.

<figure><img src="/files/AWAZBZqNkgh8mdgwr3hv" alt=""><figcaption><p>Create new scene</p></figcaption></figure>

Type the scene's name. In this example, we'll use the name `WebcamDemo`.

After the scene is created, right-click on the scene and select `GameObject > UI > Canvas`.

<figure><img src="/files/SOVl2RObo6YAMFPnsd5J" alt=""><figcaption><p>Add a Canvas</p></figcaption></figure>

Navigate to the LightBuzz `Prefabs` folder at `Assets\LightBuzz Hand Tracking\Runtime\Prefabs`.

<figure><img src="/files/aLOxlnZxIBjwQFtfkzwZ" alt=""><figcaption><p>LightBuzz Prefabs</p></figcaption></figure>

For this example, drag and drop the [ImageView](/ui-reference/imageview), [WebcamSource](/ui-reference/streamsource/webcamsource) and [HandManager](/ui-reference/handmanager) prefabs into the Canvas.

<figure><img src="/files/ihYQ5AJQowyqRRRavG1k" alt=""><figcaption><p>Add prefabs</p></figcaption></figure>

Then, right-click on the `Hierarchy` pane and select `Create Empty`.&#x20;

<figure><img src="/files/tWKAoCSDw2MNbLtdn4Dg" alt=""><figcaption><p>Create empty component</p></figcaption></figure>

Give a name to the new component. In this example, we'll use the name `Demo`.

Then, go to the `Inspector` pane and select `Add Component`. In the search bar, type `new` and select the `New script` option.

<figure><img src="/files/aEWEKS46jXoNR0dQLnvd" alt=""><figcaption><p>Add script</p></figcaption></figure>

Type the script's name and select `Create and Add`. For this example, we'll use the name `WebcamDemo`.

<figure><img src="/files/dpZB2jLjZsSWk0DTCq2s" alt=""><figcaption><p>Create script</p></figcaption></figure>

#### Step 2: Initialize the visual components

Double-click on the newly created `MonoBehaviour` script and import the necessary namespaces.

```csharp
using LightBuzz.HandTracking;
using System.Collections.Generic;
using UnityEngine;
```

For this example, we'll need a [WebcamSource](/ui-reference/streamsource/webcamsource) to get the frames, an [ImageView](/ui-reference/imageview) to draw camera texture and a [HandManager](/ui-reference/handmanager) to visualize the detected hands.

```csharp
[SerializeField] private ImageView _image;
[SerializeField] private WebcamSource _webcam;
[SerializeField] private HandManager _handManager;
```

After adding the serialized fields, go to the Unity Editor to connect these fields with the `Demo` component.

At the `Inspector` pane, select the round button next to each `SerializeField`.

<figure><img src="/files/TsmfbgO2lPiUzRTVuBhs" alt=""><figcaption><p>Seriaze fileds</p></figcaption></figure>

Then, at the `Scene` tab, select the corresponding prefab. For example, for the `Image` field, select the `ImageView` prefab.

<figure><img src="/files/0jqp9uI7zQIPnTTMXJIa" alt=""><figcaption><p>Connect prefab</p></figcaption></figure>

When all fields are connected, the result should resemble the following image.

<figure><img src="/files/Haww42vUdpbdSN6LMQvl" alt=""><figcaption><p>Connected serialize fields</p></figcaption></figure>

Then, select the `HandManager` prefab, under the `Canvas`, and connect the `Image` field to the `ImageView` prefab.

<figure><img src="/files/J7W7y81Uo00EVQAPLrLA" alt=""><figcaption><p>Connect field to HandManager</p></figcaption></figure>

{% hint style="info" %}
Make sure the `Is 2D` option is selected to see the hand tracking detections in the 2D space. If the option is not checked, detections are displayed in the 3D world space.
{% endhint %}

After connecting all the fields, navigate to the `Canvas` to set the render options.

Change the `Render Mode` to `Screen Space - Camera`.

<figure><img src="/files/8xapwQLfkO58oNi2gJhH" alt=""><figcaption><p>Change Render Mode</p></figcaption></figure>

Then, set the `Main Camera,` from the Scene tab, as the `Render Camera`.

<figure><img src="/files/FKcxZ5Eyq9JlM0GAFHZu" alt=""><figcaption><p>Select Render Camera</p></figcaption></figure>

When all the render options are set, the result should look like the following image.

<figure><img src="/files/bVxgPsw5dk4FXW0xcKXy" alt=""><figcaption><p>Render settings</p></figcaption></figure>

Finally, return to the script and instantiate a [HandTracker](/api-reference/handtracker) to detect hands.

```csharp
HandTracker _handTracker = new HandTracker();
```

#### Step 3: Open the webcam

Open the webcam to get the live feed.&#x20;

```csharp
_webcam.Open();
```

{% hint style="info" %}
In this example, the camera is opened in the `Start()` method. Alternatively, you could open the camera with the click of a button.
{% endhint %}

#### Step 4: Get the live feed

Check that the camera is open and available for capturing video.

```csharp
if (!_webcam.IsOpen) return;
```

Load the new frame from the `_webcam` object onto the [ImageView](/ui-reference/imageview) to show the live feed to your users.

```csharp
_image.Load(_webcam);
```

#### Step 5: Detect hands

Pass the `Texture2D` object from the camera frame to the [HandTracker](/api-reference/handtracker) for processing.

```csharp
List<Hand> hands = _handTracker.Load(_image.Texture);
```

The [HandTracker](/api-reference/handtracker) will analyze the texture and detect any hands present in the image.

#### Step 6: Visualize the hands

To display the detected hands on a 2D canvas, simply pass the detections to the [HandManager](/ui-reference/handmanager).  It will manage the rendering and updates required to accurately depict the hands on the canvas based on the detection data provided.

```csharp
_handManager.Load(hands);
```

{% hint style="info" %}
Steps 4 through 6 are incorporated into the `Update()` method.
{% endhint %}

#### Step 7: Release the resources

Close the webcam to stop the live feed, preventing further video capture.

```csharp
_webcam.Close();
```

Dispose of the [HandTracker](/api-reference/handtracker) object to ensure that all associated resources are released.

```csharp
_handTracker.Dispose();
```

{% hint style="info" %}
In this example, the resources are released in the `OnDestroy()` method. Alternatively, you could do that with the click of a button or in the `OnApplicationQuit()` method.
{% endhint %}

### Full example code

Here is the full example code that has the same functionality as the Hand Tracking Unity plugin `LightBuzz_Hand_Tracking_2D` sample.

<pre class="language-csharp"><code class="lang-csharp">using LightBuzz.HandTracking;
using System.Collections.Generic;
using UnityEngine;

public class WebcamDemo : MonoBehaviour
{
    [SerializeField] private ImageView _image;
    [SerializeField] private WebcamSource _webcam;
    [SerializeField] private HandManager _handManager;
    
    private readonly HandTracker _handTracker = new HandTracker();

<strong>    private void Start()
</strong>    {
        _webcam.Open();
    }

    private void OnDestroy()
    {
        _webcam.Close();
        _handTracker.Dispose();
    }

    private void Update()
    {
        if (!_webcam.IsOpen) return;

        // 1. Draw the camera texture.
        _image.Load(_webcam);

        // 2. Detect hands in the camera texture.
        List&#x3C;Hand> hands = _handTracker.Load(_image.Texture);

        // 3. Visualize the hands on a Canvas.
        _handManager.Load(hands);
    }
}
</code></pre>

By following these steps, you will be able to load the camera feed into your application, detect hands in real time, and finally, render these detections on a 2D canvas.


# Use webcam to detect and visualize hands (3D World space)

An example on how to get camera feed, detect and visualize hands in real time in 3D world space.

This example demonstrates how to load and display camera feed in a Unity scene with a [WebcamSource](/ui-reference/streamsource/webcamsource) and an [ImageView](/ui-reference/imageview), implement hand tracking with the [HandTracker](/api-reference/handtracker), and use the [HandManager](/ui-reference/handmanager) to render detected fingers in 3D world space.

{% hint style="info" %}
This is a code walkthrough of the `LightBuzz_Hand_Tracking_3D` Hand Tracking Unity plugin sample. The plugin includes the no-code demo that has the same functionality.
{% endhint %}

#### Step 1: Create a Unity scene

Open the Unity Project you created in the [Installation](/hand-tracking-unity-plugin/installation) section.

Right-click on the `Assets` folder and select `Create > Scene`.

<figure><img src="/files/AWAZBZqNkgh8mdgwr3hv" alt=""><figcaption><p>Create new scene</p></figcaption></figure>

Type the scene's name. In this example, we'll use the name `WebcamDemo3D`.

After the scene is created, right-click on the scene and select `GameObject > UI > Canvas`.

<figure><img src="/files/SOVl2RObo6YAMFPnsd5J" alt=""><figcaption><p>Add a Canvas</p></figcaption></figure>

Navigate to the LightBuzz `Prefabs` folder at `Assets\LightBuzz Hand Tracking\Runtime\Prefabs`.

<figure><img src="/files/aLOxlnZxIBjwQFtfkzwZ" alt=""><figcaption><p>LightBuzz Prefabs</p></figcaption></figure>

For this example, you'll need the [ImageView](/ui-reference/imageview), [WebcamSource](/ui-reference/streamsource/webcamsource) and [HandManager](/ui-reference/handmanager) prefabs.&#x20;

Drag and drop the [ImageView](/ui-reference/imageview) and [WebcamSource](/ui-reference/streamsource/webcamsource) prefabs into the Canvas. &#x20;

<figure><img src="/files/m36wjE6nTUneD2ruo4HM" alt=""><figcaption><p>Add prefabs into Canvas</p></figcaption></figure>

Drag and drop the [HandManager](/ui-reference/handmanager) prefab on the `Hierarchy` pane (but not into the Canvas).

<figure><img src="/files/WDJcKrMEXOkJa6poicx1" alt=""><figcaption><p>Add HandManager prefab</p></figcaption></figure>

{% hint style="info" %}
To see the 3D detections, the [HandManager](/ui-reference/handmanager) needs to be outside of the Canvas.
{% endhint %}

Then, right-click on the `Hierarchy` pane and select `Create Empty`.&#x20;

<figure><img src="/files/tWKAoCSDw2MNbLtdn4Dg" alt=""><figcaption><p>Create empty component</p></figcaption></figure>

Give a name to the new component. In this example, we'll use the name `Demo`.

Then, go to the `Inspector` pane and select `Add Component`. In the search bar, type `new` and select the `New script` option.

<figure><img src="/files/aEWEKS46jXoNR0dQLnvd" alt=""><figcaption><p>Add script</p></figcaption></figure>

Type the script's name and select `Create and Add`. For this example, we'll use the name `WebcamDemo3D`.

<figure><img src="/files/zrZO7f0pmDbhxX4USliJ" alt=""><figcaption><p>Create script</p></figcaption></figure>

#### Step 2: Initialize the visual components

Double-click on the newly created `MonoBehaviour` script and import the necessary namespaces.

```csharp
using LightBuzz.HandTracking;
using System.Collections.Generic;
using UnityEngine;
```

For this example, we'll need a [WebcamSource](/ui-reference/streamsource/webcamsource) to get the frames, an [ImageView](/ui-reference/imageview) to draw camera texture and a [HandManager](/ui-reference/handmanager) to visualize the detected hands.

```csharp
[SerializeField] private ImageView _image;
[SerializeField] private WebcamSource _webcam;
[SerializeField] private HandManager _handManager;
```

After adding the serialized fields, go to the Unity Editor to connect these fields with the `Demo` component.

At the `Inspector` pane, select the round button next to each `SerializeField`.

<figure><img src="/files/D3ObTztBSLXTEO3Gjozb" alt=""><figcaption><p>Seriaze fileds</p></figcaption></figure>

Then, at the `Scene` tab, select the corresponding prefab. For example, for the `Image` field, select the `ImageView` prefab.

<figure><img src="/files/0jqp9uI7zQIPnTTMXJIa" alt=""><figcaption><p>Connect prefab</p></figcaption></figure>

When all fields are connected, the result should resemble the following image.

<figure><img src="/files/f7eZuKbKE9ORlaKubk8w" alt=""><figcaption><p>Connected serialize fields</p></figcaption></figure>

Then, select the `HandManager` prefab. Connect the `Image` field to the `ImageView` prefab and uncheck the `Is 2D` option.

<figure><img src="/files/ULjdMjKeNz1qUSRheNMl" alt=""><figcaption><p>Connect field to HandManager</p></figcaption></figure>

{% hint style="warning" %}
Make sure the `Is 2D` option is NOT selected to see the hand tracking detections in the 3D world space. If the option is checked, detections are displayed in the 2D space.
{% endhint %}

After connecting all the fields, navigate to the `Canvas` to set the render options.

Change the `Render Mode` to `Screen Space - Camera`.

<figure><img src="/files/8xapwQLfkO58oNi2gJhH" alt=""><figcaption><p>Change Render Mode</p></figcaption></figure>

Then, set the `Main Camera,` from the Scene tab, as the `Render Camera`.

<figure><img src="/files/FKcxZ5Eyq9JlM0GAFHZu" alt=""><figcaption><p>Select Render Camera</p></figcaption></figure>

When all the render options are set, the result should look like the following image.

<figure><img src="/files/bVxgPsw5dk4FXW0xcKXy" alt=""><figcaption><p>Render settings</p></figcaption></figure>

#### Step 3: Adjust Scene components

To display the hand detections in the 3D world space we need to adjust the [ImageView](/ui-reference/imageview).&#x20;

Navigate to the [ImageView](/ui-reference/imageview) prefab, under the `Canvas`, go to the `Aspect Ratio Fitter` section and change `Aspect Mode` to `None`.

<figure><img src="/files/dQ7BfkukFQRNmL5k8OER" alt=""><figcaption><p>Aspect Mode settings</p></figcaption></figure>

Then, go to the `Rect Transform` section of the [ImageView](/ui-reference/imageview) prefab and click on the blue cross to open the `Anchor Presets`.

<figure><img src="/files/efgFtJcUV2OjmIABFM1L" alt=""><figcaption><p>Anchor Presets</p></figcaption></figure>

Select the `middle` and `center` option (the one that looks like a target).&#x20;

Then, change the `Width` to `400`, the `Height` to `200` and the `Pos X` to `-600`.

<figure><img src="/files/Vd4nnpxld4ec6ZrIHs9T" alt=""><figcaption><p>Rect Transform</p></figcaption></figure>

{% hint style="info" %}
The suggested `Rect Transform` settings are designed to reduce the size of the [ImageView](/ui-reference/imageview) and reposition it to the side. Feel free to experiment and set the settings to different values.
{% endhint %}

For a proper view, navigate to the `Main Camera` component and set the `Y Position` to `0`, since the 3D coordinates of the hands are estimated relative to the cartesian origin point. Also, set the `Z Position` to `-1` to move the camera farther from the hands.

<figure><img src="/files/3mjNpp5QwaNbHfSklljp" alt=""><figcaption><p>Main Camera Transform</p></figcaption></figure>

Finally, return to the `MonoBehaviour` script and instantiate a [HandTracker](/api-reference/handtracker) to detect hands.

```csharp
HandTracker _handTracker = new HandTracker();
```

#### Step 4: Open the webcam

Open the webcam to get the live feed.

```csharp
_webcam.Open();
```

{% hint style="info" %}
In this example, the camera is opened in the `Start()` method. Alternatively, you could open the camera with the click of a button.
{% endhint %}

#### Step 5: Get the live feed

Check that the camera is open and available for capturing video.

```csharp
if (!_webcam.IsOpen) return;
```

Load the new frame from the `_webcam` object onto the [ImageView](/ui-reference/imageview) to show the live feed to your users.

```csharp
_image.Load(_webcam);
```

#### Step 6: Detect hands

Pass the `Texture2D` object from the camera frame to the [HandTracker](/api-reference/handtracker) for processing.

```csharp
List<Hand> hands = _handTracker.Load(_image.Texture);
```

The [HandTracker](/api-reference/handtracker) will analyze the texture and detect any hands present in the image.

#### Step 7: Visualize the hands

To display the detected hands in 3D world space, first sort the hands by position X.

```csharp
hands.Sort((h1, h2) => 
    h1[FingerJointType.Root].Position2D.x.CompareTo(
        h2[FingerJointType.Root].Position2D.x));
```

{% hint style="warning" %}
By default, the [HandManager](/ui-reference/handmanager) positions the root joint of any detected hand at the origin point (0, 0, 0) within the 3D world space. To track multiple hands and visualize them clearly within the 3D environment, you need to provide an offset value in meters for each hand. Provided with an offset list, the [HandManager](/ui-reference/handmanager) will reposition each hand according to the offset value.
{% endhint %}

In this example, each new hand will be positioned 25 cm away from the previous one.

```csharp
List<Vector3> offsets = new List<Vector3>();
float offset_x = 0f;
float step = 0.25f;

foreach (Hand hand in hands)
{
    offsets.Add(new Vector3(offset_x, 0f, 0f));
    offset_x += step;
}
```

Then, simply pass the hand detections and the offsets to the [HandManager](/ui-reference/handmanager).  It will manage the rendering and updates required to accurately depict the hands in 3D world space based on the detection data provided.

```csharp
_handManager.Load(hands, offsets);
```

{% hint style="info" %}
Steps 5 through 7 are incorporated into the `Update()` method.
{% endhint %}

#### Step 8: Release the resources

Close the webcam to stop the live feed, preventing further video capture.

```csharp
_webcam.Close();
```

Dispose of the [HandTracker](/api-reference/handtracker) object to ensure that all associated resources are released.

```csharp
_handTracker.Dispose();
```

{% hint style="info" %}
In this example, the resources are released in the `OnDestroy()` method. Alternatively, you could do that with the click of a button or in the `OnApplicationQuit()` method.
{% endhint %}

### Full example code

Here is the full example code that has the same functionality as the Hand Tracking Unity plugin `LightBuzz_Hand_Tracking_3D` sample.

<pre class="language-csharp"><code class="lang-csharp">using LightBuzz.HandTracking;
using System.Collections.Generic;
using UnityEngine;

public class WebcamDemo3D : MonoBehaviour
{
    [SerializeField] private ImageView _image;
    [SerializeField] private WebcamSource _webcam;
    [SerializeField] private HandManager _handManager;
    
    private readonly HandTracker _handTracker = new HandTracker();

<strong>    private void Start()
</strong>    {
        _webcam.Open();
    }

    private void OnDestroy()
    {
        _webcam.Close();
        _handTracker.Dispose();
    }

    private void Update()
    {
        if (!_webcam.IsOpen) return;

        // 1. Draw the camera texture.
        _image.Load(_webcam);

        // 2. Detect hands in the camera texture.
        List&#x3C;Hand> hands = _handTracker.Load(_image.Texture);
        
        // 3. Sort hands by position X.
        hands.Sort((h1, h2) => 
            h1[FingerJointType.Root].Position2D.x.CompareTo(
                h2[FingerJointType.Root].Position2D.x));

        // 4. Add offset to show all detected hands.
        List&#x3C;Vector3> offsets = new List&#x3C;Vector3>();
        float offset_x = 0f;
        float step = 0.25f;

        foreach (Hand hand in hands)
        {
            offsets.Add(new Vector3(offset_x, 0f, 0f));
            offset_x += step;
        }

        // 5. Visualize the hands on a Canvas.
        _handManager.Load(hands, offsets);
    }
}
</code></pre>

By following these steps, you will be able to load the camera feed into your application, detect hands in real time, and finally, render these detections in 3D world space.


# Finger

Represents a finger with all its relevant joints.

```csharp
public class Finger
```

### Constructors

| Name                                                                                                             | Description                                                                          |
| ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| Finger()                                                                                                         | Creates a new Finger object.                                                         |
| Finger(Dictionary<[FingerJointType](/api-reference/fingerjointtype), [FingerJoint](/api-reference/fingerjoint)>) | Creates a new Finger object with the specified finger joint types and finger joints. |

### Example

The example shows how to manage a finger with the `Finger` class.

#### Create a finger with the specified finger joints

```csharp
// Create an index Tip joint with the specified 2D position and 
// 3D position.
FingerJoint indexTip = new FingerJoint
(
    FingerJointType.IndexTip,
    new Vector2(3, 3),
    new Vector3(0.3f, 0.3f, 0.3f),
    new Quaternion()
);

// Create an index DIP joint with the specified 2D position and 
// 3D position.
FingerJoint indexDIP = new FingerJoint
(
    FingerJointType.IndexDIP,
    new Vector2(3, 3),
    new Vector3(0.3f, 0.3f, 0.3f),
    new Quaternion()
);

 // Create an index finger with the specified index joints.
 Finger index = new Finger
 (
     new Dictionary<FingerJointType, FingerJoint> 
     {
         { FingerJointType.IndexTip, indexTip },
         { FingerJointType.IndexDIP,indexDIP }
     }
 );
```

#### Create an empty finger

```csharp
Finger emptyFinger = new Finger();
```


# Index

Represents an index finger with all its relevant joints.

{% hint style="warning" %}
The `Hand` class automatically instantiates the `Index` class for you.
{% endhint %}

```csharp
public class Index : Finger
```

Inherits [Finger ](/api-reference/finger)class.

### Constructors

| Name                                                                                                            | Description                                                                         |
| --------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| Index(Dictionary<[FingerJointType](/api-reference/fingerjointtype), [FingerJoint](/api-reference/fingerjoint)>) | Creates a new Index object with the specified finger joint types and finger joints. |

### Properties

| Name | Type                                      | Description                                                 |
| ---- | ----------------------------------------- | ----------------------------------------------------------- |
| MCP  | [FingerJoint](/api-reference/fingerjoint) | Read-Only. The index finger metacarpophalangeal joint.      |
| PIP  | [FingerJoint](/api-reference/fingerjoint) | Read-Only. The index finger proximal interphalangeal joint. |
| DIP  | [FingerJoint](/api-reference/fingerjoint) | Read-Only. The index finger distal interphalangeal joint.   |
| Tip  | [FingerJoint](/api-reference/fingerjoint) | Read-Only. The index finger tip joint.                      |

### Example

The example shows how to manage an index finger with the `Index` class.

#### Create an index finger with a constructor

```csharp
// Create an index tip joint with the specified 2D position and 
// 3D position.
FingerJoint indexTip = new FingerJoint
(
    FingerJointType.IndexTip, 
    new Vector2(3, 3), 
    new Vector3(0.3f, 0.3f, 0.3f),
    new Quaternion()
);

// Create an index DIP joint with the specified 2D position and 
// 3D position.
FingerJoint indexDIP = new FingerJoint
(
    FingerJointType.IndexDIP,
    new Vector2(3, 3),
    new Vector3(0.3f, 0.3f, 0.3f),
    new Quaternion()
);

 // Create an index finger with the specified index joints.
 Index index = new Index
 (
     new Dictionary<FingerJointType, FingerJoint> 
     {
         { FingerJointType.IndexTip, indexTip },
         { FingerJointType.IndexDIP, indexDIP }
     }
 );
```

#### Get joint information from an index finger

```csharp
// Get index Tip joint.
FingerJoint indexTipNew = index.Tip;
```


# Middle

Represents a middle finger with all its relevant joints.

{% hint style="warning" %}
The `Hand` class automatically instantiates the `Middle` class for you.
{% endhint %}

```csharp
public class Middle : Finger
```

Inherits [Finger ](/api-reference/finger)class.

### Constructors

| Name                                                                                                             | Description                                                                          |
| ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| Middle(Dictionary<[FingerJointType](/api-reference/fingerjointtype), [FingerJoint](/api-reference/fingerjoint)>) | Creates a new Middle object with the specified finger joint types and finger joints. |

### Properties

| Name | Type                                      | Description                                                  |
| ---- | ----------------------------------------- | ------------------------------------------------------------ |
| MCP  | [FingerJoint](/api-reference/fingerjoint) | Read-Only. The middle finger metacarpophalangeal joint.      |
| PIP  | [FingerJoint](/api-reference/fingerjoint) | Read-Only. The middle finger proximal interphalangeal joint. |
| DIP  | [FingerJoint](/api-reference/fingerjoint) | Read-Only. The middle finger distal interphalangeal joint.   |
| Tip  | [FingerJoint](/api-reference/fingerjoint) | Read-Only. The middle finger tip joint.                      |

### Example

The example shows how to manage a middle finger with the `Middle`class.

#### Create a middle finger with a constructor

```csharp
// Create a middle tip joint with the specified 2D position and 
// 3D position.
FingerJoint middleTip = new FingerJoint
(
    FingerJointType.MiddleTip,
    new Vector2(3, 3),
    new Vector3(0.3f, 0.3f, 0.3f),
    new Quaternion()
);

// Create a middle DIP joint with the specified 2D position and 
// 3D position.
FingerJoint middleDIP = new FingerJoint
(
    FingerJointType.MiddleDIP,
    new Vector2(3, 3),
    new Vector3(0.3f, 0.3f, 0.3f),
    new Quaternion()
);

// Create a middle finger with the specified middle joints.
Middle middle = new Middle
(
     new Dictionary<FingerJointType, FingerJoint> 
     {
         { FingerJointType.MiddleTip, middleTip },
         { FingerJointType.MiddleDIP, middleDIP }
     }
 );
```

#### Get joint information from a middle finger

```csharp
// Get middle Tip joint.
FingerJoint middleTipNew = middle.Tip;
```


# Palm

Represents a palm finger with all its relevant joints.

{% hint style="warning" %}
The `Hand` class automatically instantiates the `Palm` class for you.
{% endhint %}

```csharp
public class Palm : Finger
```

Inherits [Finger ](/api-reference/finger)class.

### Constructors

| Name                                                                                                           | Description                                                                        |
| -------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| Palm(Dictionary<[FingerJointType](/api-reference/fingerjointtype), [FingerJoint](/api-reference/fingerjoint)>) | Creates a new Palm object with the specified finger joint types and finger joints. |

### Properties

| Name      | Type                                      | Description                                             |
| --------- | ----------------------------------------- | ------------------------------------------------------- |
| Wrist     | [FingerJoint](/api-reference/fingerjoint) | Read-Only. The root of the hand.                        |
| Center    | [FingerJoint](/api-reference/fingerjoint) | Read-Only. The middle of the palm.                      |
| ThumbCMP  | [FingerJoint](/api-reference/fingerjoint) | Read-Only. The thumb carpometacarpal joint.             |
| ThumbMCP  | [FingerJoint](/api-reference/fingerjoint) | Read-Only. The thumb metacarpophalangeal joint.         |
| IndexMCP  | [FingerJoint](/api-reference/fingerjoint) | Read-Only. The index finger metacarpophalangeal joint.  |
| MiddleMCP | [FingerJoint](/api-reference/fingerjoint) | Read-Only. The middle finger metacarpophalangeal joint. |
| RingMCP   | [FingerJoint](/api-reference/fingerjoint) | Read-Only. The ring finger metacarpophalangeal joint.   |
| PinkyMCP  | [FingerJoint](/api-reference/fingerjoint) | Read-Only. The pinky finger metacarpophalangeal joint.  |

### Example

The example shows how to manage a palm with the `Palm` class.

#### Create a palm with a constructor

```csharp
// Create a thumb MCP joint with the specified 2D position and 
// 3D position.
FingerJoint thumbMCP = new FingerJoint
(
    FingerJointType.ThumbMCP,
    new Vector2(3, 3),
    new Vector3(0.3f, 0.3f, 0.3f),
    new Quaternion()
);

// Create a pinky MCP joint with the specified 2D position and 
// 3D position.
FingerJoint pinkyMCP = new FingerJoint
(
    FingerJointType.PinkyMCP,
    new Vector2(3, 3),
    new Vector3(0.3f, 0.3f, 0.3f),
    new Quaternion()
);

 // Create a palm with the specified joints.
 Palm palm = new Palm
 (
     new Dictionary<FingerJointType, FingerJoint> 
     {
         { FingerJointType.ThumbMCP, thumbMCP },
         { FingerJointType.PinkyMCP, pinkyMCP }
     }
 );
```

#### Get joint information from a palm

```csharp
// Get palm pinky MCP joint.
FingerJoint pinkyMCPNew = palm.PinkyMCP;
```


# Pinky

Represents a pinky finger with all its relevant joints.

{% hint style="warning" %}
The `Hand` class automatically instantiates the `Pinky` class for you.
{% endhint %}

```csharp
public class Pinky : Finger
```

Inherits [Finger ](/api-reference/finger)class.

### Constructors

| Name                                                                                                            | Description                                                                         |
| --------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| Pinky(Dictionary<[FingerJointType](/api-reference/fingerjointtype), [FingerJoint](/api-reference/fingerjoint)>) | Creates a new Pinky object with the specified finger joint types and finger joints. |

### Properties

| Name | Type                                      | Description                                                 |
| ---- | ----------------------------------------- | ----------------------------------------------------------- |
| MCP  | [FingerJoint](/api-reference/fingerjoint) | Read-Only. The pinky finger metacarpophalangeal joint.      |
| PIP  | [FingerJoint](/api-reference/fingerjoint) | Read-Only. The pinky finger proximal interphalangeal joint. |
| DIP  | [FingerJoint](/api-reference/fingerjoint) | Read-Only. The pinky finger distal interphalangeal joint.   |
| Tip  | [FingerJoint](/api-reference/fingerjoint) | Read-Only. The pinky finger tip joint.                      |

### Example

The example shows how to manage a pinky finger with the `Pinky` class.

#### Create a pinky finger with a constructor

```csharp
// Create a pinky tip joint with the specified 2D position and 
// 3D position.
FingerJoint pinkyTip = new FingerJoint
(
    FingerJointType.PinkyTip,
    new Vector2(3, 3),
    new Vector3(0.3f, 0.3f, 0.3f),
    new Quaternion()
);

// Create a pinky DIP joint with the specified 2D position and 
// 3D position.
FingerJoint pinkyDIP = new FingerJoint
(
    FingerJointType.PinkyDIP,
    new Vector2(3, 3),
    new Vector3(0.3f, 0.3f, 0.3f),
    new Quaternion()
);

 // Create a pinky finger with the specified pinky joints.
 Pinky pinky = new Pinky
 (
     new Dictionary<FingerJointType, FingerJoint> 
     {
         { FingerJointType.PinkyTip, pinkyTip },
         { FingerJointType.PinkyDIP, pinkyDIP }
     }
 );
```

#### Get joint information from a pinky finger

```csharp
// Get pinky Tip joint.
FingerJoint pinkyTipNew = pinky.Tip;
```


# Ring

Represents a ring finger with all its relevant joints.

{% hint style="warning" %}
The `Hand` class automatically instantiates the `Ring` class for you.
{% endhint %}

```csharp
public class Ring : Finger
```

Inherits [Finger ](/api-reference/finger)class.

### Constructors

| Name                                                                                                           | Description                                                                        |
| -------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| Ring(Dictionary<[FingerJointType](/api-reference/fingerjointtype), [FingerJoint](/api-reference/fingerjoint)>) | Creates a new Ring object with the specified finger joint types and finger joints. |

### Properties

| Name | Type                                      | Description                                                |
| ---- | ----------------------------------------- | ---------------------------------------------------------- |
| MCP  | [FingerJoint](/api-reference/fingerjoint) | Read-Only. The ring finger metacarpophalangeal joint.      |
| PIP  | [FingerJoint](/api-reference/fingerjoint) | Read-Only. The ring finger proximal interphalangeal joint. |
| DIP  | [FingerJoint](/api-reference/fingerjoint) | Read-Only. The ring finger distal interphalangeal joint.   |
| Tip  | [FingerJoint](/api-reference/fingerjoint) | Read-Only. The ring finger tip joint.                      |

### Example

The example shows how to manage a ring finger with the `Ring`class.

#### Create a ring finger with a constructor

```csharp
// Create a ring tip joint with the specified 2D position and 
// 3D position.
FingerJoint ringTip = new FingerJoint
(
    FingerJointType.RingTip,
    new Vector2(3, 3),
    new Vector3(0.3f, 0.3f, 0.3f),
    new Quaternion()
);

// Create a ring DIP joint with the specified 2D position and 
// 3D position.
FingerJoint ringDIP = new FingerJoint
(
    FingerJointType.RingDIP,
    new Vector2(3, 3),
    new Vector3(0.3f, 0.3f, 0.3f),
    new Quaternion()
);

 // Create a ring finger with the specified ring joints.
 Ring ring = new Ring
 (
     new Dictionary<FingerJointType, FingerJoint> 
     {
         { FingerJointType.RingTip, ringTip },
         { FingerJointType.RingDIP, ringDIP }
     }
 );
```

#### Get joint information from a ring finger

```csharp
// Get ring Tip joint.
FingerJoint ringTipNew = ring.Tip;
```


# Thumb

Represents a thumb with all its relevant joints.

{% hint style="warning" %}
The `Hand` class automatically instantiates the `Thumb` class for you.
{% endhint %}

```csharp
public class Thumb : Finger
```

Inherits [Finger ](/api-reference/finger)class.

### Constructors

| Name                                                                                                            | Description                                                                         |
| --------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| Thumb(Dictionary<[FingerJointType](/api-reference/fingerjointtype), [FingerJoint](/api-reference/fingerjoint)>) | Creates a new Thumb object with the specified finger joint types and finger joints. |

### Properties

| Name | Type                                      | Description                                     |
| ---- | ----------------------------------------- | ----------------------------------------------- |
| CMC  | [FingerJoint](/api-reference/fingerjoint) | Read-Only. The thumb carpometacarpal joint.     |
| MCP  | [FingerJoint](/api-reference/fingerjoint) | Read-Only. The thumb metacarpophalangeal joint. |
| IP   | [FingerJoint](/api-reference/fingerjoint) | Read-Only. The thumb interphalangeal joint.     |
| Tip  | [FingerJoint](/api-reference/fingerjoint) | Read-Only. The thumb tip joint.                 |

### Example

The example shows how to manage a thumb with the `Thumb`class.

#### Create a thumb with a constructor

```csharp
// Create a thumb tip joint with the specified 2D position and 
// 3D position.
FingerJoint thumbTip = new FingerJoint
(
    FingerJointType.ThumbTip,
    new Vector2(3, 3),
    new Vector3(0.3f, 0.3f, 0.3f),
    new Quaternion()
);

// Create a thumb IP joint with the specified 2D position and 
// 3D position.
FingerJoint thumbIP = new FingerJoint
(
    FingerJointType.ThumbIP,
    new Vector2(3, 3),
    new Vector3(0.3f, 0.3f, 0.3f),
    new Quaternion()
);

 // Create a thumb with the specified thumb joints.
 Thumb thumb = new Thumb
 (
     new Dictionary<FingerJointType, FingerJoint> 
     {
         { FingerJointType.ThumbTip, thumbTip },
         { FingerJointType.ThumbIP, thumbIP }
     }
 );
```

#### Get joint information from a thumb

```csharp
// Get thumb Tip joint.
FingerJoint thumbTipNew = thumb.Tip;
```


# FingerJoint

Represents a finger joint.

```csharp
public class FingerJoint
```

### Constructors

| Name                                                                                                                                                                                                                                                                                                           | Description                                                                                                               |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| FingerJoint()                                                                                                                                                                                                                                                                                                  | Creates a new FingerJoint object.                                                                                         |
| FingerJoint([FingerJoint](/api-reference/fingerjoint))                                                                                                                                                                                                                                                         | Creates a new FingerJoint object by copying the data from the specified finger joint.                                     |
| FingerJoint([FingerJointType](/api-reference/fingerjointtype), [UnityEngine.Vector2](https://docs.unity3d.com/ScriptReference/Vector2.html), [UnityEngine.Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html), [UnityEngine.Quaternion](https://docs.unity3d.com/ScriptReference/Quaternion.html)) | Creates a new FingerJoint object with the specified type, 2D position,3D position and 3D orientation of the finger joint. |

### Properties

| Name        | Type                                                                               | Description                                    |
| ----------- | ---------------------------------------------------------------------------------- | ---------------------------------------------- |
| Type        | [FingerJointType](/api-reference/fingerjointtype)                                  | The type of the finger joint.                  |
| Position2D  | [UnityEngine.Vector2](https://docs.unity3d.com/ScriptReference/Vector2.html)       | The 2D position of the finger joint in pixels. |
| Position3D  | [UnityEngine.Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html)       | The 3D position of the finger joint in meters. |
| Orientation | [UnityEngine.Quaternion](https://docs.unity3d.com/ScriptReference/Quaternion.html) | The 3D orientation of the joint.               |

### Methods

| Name                                         | Return Type | Description                                                                           |
| -------------------------------------------- | ----------- | ------------------------------------------------------------------------------------- |
| ToString()                                   | string      | Converts the value of this instance to a string.                                      |
| Equals([Finger](/api-reference/fingerjoint)) | bool        | Determines whether the specified Finger object is equal to the current Finger object. |
| GetHashCode()                                | int         | Returns a hash code for the current Finger object.                                    |

### Example

The example shows how to create a finger joint with the `FingerJoint` class.

#### Create a finger joint with the specified 2D position and 3D position

```csharp
FingerJoint indexTip = new FingerJoint
(
    FingerJointType.IndexTip,
    new Vector2(3, 3),
    new Vector3(0.3f, 0.3f, 0.3f),
    new Quaternion()
);
```

#### Create a finger joint with the specified finger joint

```csharp
FingerJoint indexTipNew = new FingerJoint(indexTip);
```

#### Create an empty finger joint

<pre class="language-csharp"><code class="lang-csharp"><strong>FingerJoint emptyJoint = new FingerJoint();
</strong></code></pre>


# FingerJointType

The enumeration representing the supported finger joint types.

| Name      | Index | Description                                       |
| --------- | ----- | ------------------------------------------------- |
| Root      | 0     | The root of the hand.                             |
| ThumbCMC  | 1     | The thumb carpometacarpal joint.                  |
| ThumbMCP  | 2     | The thumb metacarpophalangeal joint.              |
| ThumbIP   | 3     | The thumb interphalangeal joint.                  |
| ThumbTip  | 4     | The thumb tip joint.                              |
| IndexMCP  | 5     | The index finger metacarpophalangeal joint.       |
| IndexPIP  | 6     | The index finger proximal interphalangeal joint.  |
| IndexDIP  | 7     | The index finger distal interphalangeal joint.    |
| IndexTip  | 8     | The index finger tip joint.                       |
| MiddleMCP | 9     | The middle finger metacarpophalangeal joint.      |
| MiddlePIP | 10    | The middle finger proximal interphalangeal joint. |
| MiddleDIP | 11    | The middle finger distal interphalangeal joint.   |
| MiddleTip | 12    | The middle finger tip joint.                      |
| RingMCP   | 13    | The ring finger metacarpophalangeal joint.        |
| RingPIP   | 14    | The ring finger proximal interphalangeal joint.   |
| RingDIP   | 15    | The ring finger distal interphalangeal joint.     |
| RingTip   | 16    | The ring finger tip joint.                        |
| PinkyMCP  | 17    | The pinky finger metacarpophalangeal joint.       |
| PinkyPIP  | 18    | The pinky finger proximal interphalangeal joint.  |
| PinkyDIP  | 19    | The pinky finger distal interphalangeal joint.    |
| PinkyTip  | 20    | The pinky finger tip joint.                       |
| Palm      | 21    | The middle of the palm.                           |


# Hand

Represents a human hand.

```csharp
public class Hand
```

### Constructors

| Name                                                                                                                                                            | Description                                                                           |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| Hand()                                                                                                                                                          | Creates a new Hand object.                                                            |
| Hand([Hand](/api-reference/hand))                                                                                                                               | Creates a new Hand object by copying the data from the specified hand.                |
| Hand(int, [HandSide](/api-reference/handside), float, Dictionary<[FingerJointType](/api-reference/fingerjointtype), [FingerJoint](/api-reference/fingerjoint)>) | Creates a new Hand object with the specified id, type, confidence, and finger joints. |

### Properties

| Name                                                     | Type                                                                                                     | Description                                   |
| -------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | --------------------------------------------- |
| ID                                                       | int                                                                                                      | The ID of the hand.                           |
| Side                                                     | [HandSide](/api-reference/handside)                                                                      | The side of the hand (left or right).         |
| Confidence                                               | float                                                                                                    | The tracking confidence of the hand (0 to 1). |
| FingerJoints                                             | Dictionary<[FingerJointType](/api-reference/fingerjointtype), [FingerJoint](/api-reference/fingerjoint)> | The finger joints of the hand.                |
| Thumb                                                    | [Thumb](/api-reference/finger/thumb)                                                                     | The thumb of the hand.                        |
| Index                                                    | [Index](/api-reference/finger/index)                                                                     | The index finger of the hand.                 |
| Middle                                                   | [Middle](/api-reference/finger/middle)                                                                   | The middle finger of the hand.                |
| Ring                                                     | [Ring](/api-reference/finger/ring)                                                                       | The ring finger of the hand.                  |
| Pinky                                                    | [Pinky](/api-reference/finger/pinky)                                                                     | The pinky finger of the hand.                 |
| Palm                                                     | [Palm](/api-reference/finger/palm)                                                                       | The palm of the hand.                         |
| this\[[FingerJointType](/api-reference/fingerjointtype)] | [FingerJoint](/api-reference/fingerjoint)                                                                | Read-Only. The specified finger joint.        |
| IsOpen                                                   | bool                                                                                                     | Read-Only. If the palm is open or closed.     |
| BoundingBox2D                                            | [UnityEngine.Rect](https://docs.unity3d.com/ScriptReference/Rect.html)                                   | Read-Only. The 3D bounding box of the hand.   |
| BoundingBox3D                                            | [UnityEngine.Rect](https://docs.unity3d.com/ScriptReference/Rect.html)                                   | Read-Only. The 3D bounding box of the hand.   |

### Methods

| Name                                                      | Return Type                               | Description                                                     |
| --------------------------------------------------------- | ----------------------------------------- | --------------------------------------------------------------- |
| ToJson()                                                  | string                                    | Converts the value of this instance to a Json formatted string. |
| Parent([FingerJointType](/api-reference/fingerjointtype)) | [FingerJoint](/api-reference/fingerjoint) | Returns the Parent joint.                                       |
| Child([FingerJointType](/api-reference/fingerjointtype))  | [FingerJoint](/api-reference/fingerjoint) | Returns the Child joint.                                        |

### Example

The examples show how to manage a hand with the `Hand` class.

#### Create a hand object

To create a hand object, start by creating a dictionary of `FingerJoint` objects.

```csharp
Dictionary<FingerJointType, FingerJoint> fingerJoints = new Dictionary<FingerJointType, FingerJoint>();
fingerJoints.Add(FingerJointType.IndexTip, indexTip);
fingerJoints.Add(FingerJointType.IndexDIP, indexDIP);
```

Then, there are 3 supported constructors to create a hand object.

Create a hand object with the specified ID, type, confidence and finger joints.

```csharp
Hand rightHand = new Hand(1, HandSide.Right, 0.5f, fingerJoints);
```

Create an empty hand object and assign values to each property.

```csharp
Hand leftHand = new Hand();

leftHand.ID = 2;
leftHand.Side = HandSide.Left;
leftHand.Confidence = 0.5f;
leftHand.FingerJoints = fingerJoints;

```

Create a hand object by copying the values of another hand object.

```csharp
Hand rightHandCopy = new Hand(rightHand);
```

#### Get finger and joint information from a hand

To retrieve finger and finger joint information from a hand object, you can retrieve the finger from the hand and then get the finger joint from the finger.

```csharp
// Get the index finger from the hand.
Index index = rightHand.Index;

// Get the index tip joint from the retrieved finger.
FingerJoint rightIndexTip = index.Tip;
```

Alternatively, you can get the finger joint information directly from the hand object.

```csharp
FingerJoint rightIndexTipNew = rightHand.Index.Tip;
```


# HandExtensions

Extension methods for the Hand class.

```csharp
public static class HandExtensions
```

This is a static class.

### Methods

| Name                                         | Return Type                 | Description                                                                                         |
| -------------------------------------------- | --------------------------- | --------------------------------------------------------------------------------------------------- |
| Center(List<[Hand](/api-reference/hand)>)    | [Hand](/api-reference/hand) | Static. Returns the hand closest to the center of the field of view in the specified list of hands. |
| Leftmost(List<[Hand](/api-reference/hand)>)  | [Hand](/api-reference/hand) | Static. Returns the leftmost hand in the specified list of hands.                                   |
| Rightmost(List<[Hand](/api-reference/hand)>) | [Hand](/api-reference/hand) | Static. Returns the rightmost hand in the specified list of hands.                                  |

### Example

The examples show how to locate a hand depending on its position with the `HandExtensions` class.

#### Detect hands

First, detect the hands in an image.

```
List<Hand> hands = handTracker.Load(texture);
```

#### Retrieve the hand depending on the position

Get the hand closest to the center in the specified list of hands.

```csharp
Hand center = HandExtensions.Center(hands);
```

Get the leftmost hand in the specified list of hands.

```csharp
Hand leftmost = HandExtensions.Leftmost(hands);
```

Get the rightmost hand in the specified list of hands.

```csharp
Hand rightmost = HandExtensions.Rightmost(hands);
```


# HandSide

The enumeration representing the hand side.

| Name  | Index | Description |
| ----- | ----- | ----------- |
| Left  | 0     | Left hand.  |
| Right | 1     | Right hand. |


# HandTracker

Detects hands in an image.

```
public class HandTracker : IDisposable
```

Implements [System.IDisposable](https://learn.microsoft.com/en-us/dotnet/api/system.idisposable) interface.

### Constructors

| Name          | Description                       |
| ------------- | --------------------------------- |
| HandTracker() | Creates a new HandTracker object. |

### Properties

| Name      | Type   | Description                   |
| --------- | ------ | ----------------------------- |
| Version   | string | Read-Only. The API version.   |
| Copyright | string | Read-Only. The API copyright. |

### Methods

<table><thead><tr><th width="267">Name</th><th>Return Type</th><th>Description</th></tr></thead><tbody><tr><td>Load(<a href="https://docs.unity3d.com/ScriptReference/Texture2D.html">UnityEngine.Texture2D</a>)</td><td>List&#x3C;<a href="/pages/ygco5grQltXxU54K3jtc">Hand</a>></td><td>Detects hands for the specified Texture2D.</td></tr><tr><td>Load(<a href="https://docs.unity3d.com/ScriptReference/Color32.html">UnityEngine.Color32</a>[], int, int)</td><td>List&#x3C;<a href="/pages/ygco5grQltXxU54K3jtc">Hand</a>></td><td>Detects the hands from the specified color array, width and height.</td></tr><tr><td>Load(byte[], int, int, int)</td><td>List&#x3C;<a href="/pages/ygco5grQltXxU54K3jtc">Hand</a>></td><td>Detects hands for the specified image data, width, height and channels.</td></tr><tr><td>Dispose()</td><td>void</td><td>Releases unmanaged resources</td></tr></tbody></table>

### Example

The example shows how to detect hands with the `HandTracker` class.

#### Create a HandTracker

```csharp
HandTracker handTracker = new HandTracker();
```

#### Detect hands in Texture2D

To detect hands in a Texture2D, create a Texture2D and load an image.  There are multiple ways to load an image. You could load it from a webcam using the [WebcamSource](/ui-reference/streamsource/webcamsource), from a file in the Assets folder or from a file on your disc.

```csharp
// Create an empty Texture2D.
Texture2D texture = new Texture2D(0, 0);

// Load a file to a byte array.
string filename = "path/to/image";
byte[] rawData = System.IO.File.ReadAllBytes(filename);

// Load an byte array to the Texture2D.
texture.LoadImage(rawData);
```

After loading the image to the texture there are 3 different ways to detect hands in that image:

The simplest is to detect hands for the specified Texture2D.

```csharp
List<Hand> hands = handTracker.Load(texture);
```

If you need to run the detection in another thread, for example, you can get the texture pixels and detect hands for the specified color array.

```csharp
// Get the texture as a Color32 array.
Color32[] colors = texture.GetPixels32();

// Detect hands for the specified color array.
List<Hand> hands = handTracker.Load(colors, texture.width, texture.height);
```

Alternatively, you can get the texture raw data and detect hands for the specified byte array.

```csharp
// Get the texture as a byte array.
byte[] rawData = texture.GetRawTextureData();

// Detect hands for the specified byte array, width, height and channels.
List<Hand> hands = handTracker.Load(rawData, texture.width, texture.height, 3);
```

#### Detect hands in an image file

To detect hands in an image file, load the file and detect hands for the specified byte array.&#x20;

```csharp
// Load byte array from file.
string filename = "Assets/Images/test.png";
byte[] rawData = File.ReadAllBytes(filename);

// Detect hands for the specified byte array, width, height and channels.
List<Hand> hands = handTracker.Load(rawData, 500, 500, 3);
```

#### Dispose Handtracker

Once tracking is no longer needed, it's recommended to dispose of the `HandTracker`. You can do that either in the `OnApplicationQuit()` or the `OnDestroy()` methods.

```csharp
handTracker.Dispose();
```


# HandManager

Loads hands to a 2D Canvas or 3D space.

```csharp
public class HandManager : MonoBehaviour
```

Inherits [UnityEngine.MonoBehaviour](https://docs.unity3d.com/ScriptReference/MonoBehaviour.html) class.

### Constructors

| Name          | Description                       |
| ------------- | --------------------------------- |
| HandManager() | Creates a new HandManager object. |

### Properties

| Name        | Type                                         | Description                              |
| ----------- | -------------------------------------------- | ---------------------------------------- |
| HandVisuals | List<[HandVisual](/ui-reference/handvisual)> | A list of handVisuals.                   |
| Is2D        | bool                                         | Whether it shows the 2D or 3D positions. |

### Methods

| Name                                                                                                                        | Return Type | Description                                                                                                                                                                                           |
| --------------------------------------------------------------------------------------------------------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Load(List<[Hand](/api-reference/hand)>, List<[UnityEngine.Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html)>) | void        | Loads the specified hands to a 2D Canvas or 3D space. If an optional offset list is provided, it relocates the hands' position in 3D by the specified offset value. The offset is measured in meters. |
| Clear                                                                                                                       | void        | Removes all elements from the HandManager object.                                                                                                                                                     |

### Example

The example shows how to load detected hands to a Canvas with the `HandManager` class.

<pre class="language-csharp"><code class="lang-csharp"><strong>//Detect hands.
</strong><strong>List&#x3C;Hand> hands = handTracker.Load(image);
</strong>
// Create a handManager.
HandManager handManager= new HandManager();

// Load hands to a 2D Canvas or 3D space.
handManager.Load(hands);
</code></pre>


# HandViewer

Detects hands in an image, draws the image texture and loads hands to a 2D Canvas or 3D space.

{% hint style="info" %}
The `HandViewer` is a no-code component.
{% endhint %}

```csharp
public class HandViewer : MonoBehaviour
```

Inherits [UnityEngine.MonoBehaviour](https://docs.unity3d.com/ScriptReference/MonoBehaviour.html) class.

The `HandViewer` is a no-code component. It connects the [ImageView](/ui-reference/imageview), [HandManager](/ui-reference/handmanager) and [StreamSource](/ui-reference/streamsource) components so that you can add hand tracking to your app without a single line of code.

### Properties

| Name  | Type                              | Description                   |
| ----- | --------------------------------- | ----------------------------- |
| Hands | List<[Hand](/api-reference/hand)> | A list of the detected hands. |

### Example

A detailed example of how to detect hands, draw the image texture and load hands to a 2D Canvas or 3D space with the `HandViewer` component is included in our Examples section:

{% content-ref url="/pages/Vodof9URCBrb91OBVIRc" %}
[No Code: Detect and visualize hands from a Sprite](/examples/no-code-detect-and-visualize-hands-from-a-sprite)
{% endcontent-ref %}


# HandVisual

Visualizes finger joints using LineRenderer.

```csharp
public class HandVisual : MonoBehaviour
```

Inherits [UnityEngine.MonoBehaviour](https://docs.unity3d.com/ScriptReference/MonoBehaviour.html) class.

### Constructors

| Name         | Description                      |
| ------------ | -------------------------------- |
| HandVisual() | Creates a new HandVisual object. |

### Properties

| Name   | Type                                                                         | Description                               |
| ------ | ---------------------------------------------------------------------------- | ----------------------------------------- |
| Hand   | [Hand](/api-reference/hand)                                                  | The hand associated with the visual.      |
| Offset | [UnityEngine.Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) | The offset associated with the visual.    |
| Is2D   | bool                                                                         | Whether it shows the 2D or 3D positions.  |
| Image  | [ImageView](/ui-reference/imageview)                                         | The ImageView associated with the visual. |

### Methods

| Name                                                                                                           | Return Type | Description                                                                                                                                                                                            |
| -------------------------------------------------------------------------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Load([Hand](/api-reference/hand),[UnityEngine.Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html)) | void        | Visualizes the hand using `LineRenderer` objects. If an optional offset parameter is provided, it relocates the hand's position in 3D by the specified offset value. The offset is measured in meters. |
| Toggle(bool)                                                                                                   | void        | Sets `LineRenderer` objects to visible when set to `true`.                                                                                                                                             |

### Example

The example shows how to visualize a detected hand with the `HandVisual` class.

To visualize a hand, first, you need to instantiate a `GameObject` and get the component `HandVisual`. Then load the detected `Hand` to the specified `ImageView.`

```csharp
// Assign the prefab in the Editor.
[SerializeField] private GameObject _handPrefab;

// Instatiate GameObject.
GameObject handObject = Instantiate(_handPrefab, transform);

// Get HandVisual component.
HandVisual handVisual = handObject.GetComponent<HandVisual>();

// Visualize hand.
handVisual.Load(hand);
```


# ImageView

Draws the image texture.

```csharp
public class ImageView : MonoBehaviour
```

Inherits [UnityEngine.MonoBehaviour](https://docs.unity3d.com/ScriptReference/MonoBehaviour.html) class.

### Constructors

| Name        | Description                     |
| ----------- | ------------------------------- |
| ImageView() | Creates a new ImageView object. |

### Properties

| Name             | Type                                                                             | Description                     |
| ---------------- | -------------------------------------------------------------------------------- | ------------------------------- |
| Texture          | [UnityEngine.Texture2D](https://docs.unity3d.com/ScriptReference/Texture2D.html) | Read-Only. The image texture.   |
| Width            | int                                                                              | Read-Only. The texture width.   |
| Height           | int                                                                              | Read-Only. The texture height.  |
| FlipVertically   | bool                                                                             | Flips the texture vertically.   |
| FlipHorizontally | bool                                                                             | Flips the texture horizontally. |

### Methods

<table><thead><tr><th width="264">Name</th><th>Return Type</th><th>Description</th></tr></thead><tbody><tr><td>Load(<a href="https://docs.unity3d.com/ScriptReference/Texture2D.html">UnityEngine.Texture2D</a>)</td><td>void</td><td>Draws the texture for the specified Texture2D.</td></tr><tr><td>Load(StreamSource)</td><td>void</td><td>Draws the texture for the specified stream source.</td></tr><tr><td>Load(<a href="https://docs.unity3d.com/ScriptReference/Color32.html">UnityEngine.Color32</a>[], int, int, int)</td><td>void</td><td>Draws the texture for the specified color array, width, height and rotation.</td></tr><tr><td>Load(byte[], int, int, int)</td><td>void</td><td>Draws the texture for the specified byte array, width, height and rotation.</td></tr><tr><td>GetPosition(<a href="https://docs.unity3d.com/ScriptReference/Vector2.html">UnityEngine.Vector2</a>)</td><td><a href="https://docs.unity3d.com/ScriptReference/Vector2.html">UnityEngine.Vector2</a></td><td>Calculates the position in the local space of the image for the specified original 2D position of a point.</td></tr></tbody></table>

### Example

The example shows how to draw the texture with the `ImageView` class.

#### Draw the image texture

First,  add a [WebcamSource](/ui-reference/streamsource/webcamsource) field to get frames from a live feed and an `ImageView`field to draw the texture for Unity to serialize.&#x20;

```csharp
[SerializeField] private ImageView _image;
[SerializeField] private WebcamSource _webcam;
```

The easiest way to draw the image texture is by providing directly a [WebcamSource](/ui-reference/streamsource/webcamsource) object.

```csharp
_image.Load(_webcam);
```

Alternatively, you can provide the color array of the texture.

```csharp
_image.Load(_webcam.Pixels, _webcam.Width, _webcam.Height);
```

#### Get the local position of a finger joint

The `FingerJoint` class returns the joint's 2D position in pixels relative to the camera's dimensions. To represent this position on an `ImageView` texture, which may vary in size, the `GetPosition` method scales the joint's coordinates to match the texture's current width and height.&#x20;

```csharp
// Get the finger joint from the detected hand.
FingerJoint pinkyDip = hand.FingerJoints[FingerJointType.PinkyDIP];

// Get the original 2D position (pixels in the camera frame).
Vector2 original_position = pinkyDip.Position2D;

// Get the local 2D position (pixels in the ImageView texture).
Vector2 local_position = image.GetPosition(original_position);
```


# StreamSource

Represents a stream source.

```csharp
public class StreamSource : MonoBehaviour
```

Inherits [UnityEngine.MonoBehaviour](https://docs.unity3d.com/ScriptReference/MonoBehaviour.html) class.

### Constructors

| Name           | Description                        |
| -------------- | ---------------------------------- |
| StreamSource() | Creates a new StreamSource object. |

### Properties

| Name      | Type                                                                            | Description                                                          |
| --------- | ------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| Timestamp | DateTime                                                                        | Virtual. The stream timestamp.                                       |
| Pixels    | [UnityEngine.Color32](https://docs.unity3d.com/ScriptReference/Color32.html)\[] | Virtual. The pixel color data for a mipmap level as Color32 structs. |
| Width     | int                                                                             | Virtual. The width of the WebcamTexture in pixels.                   |
| Height    | int                                                                             | Virtual. The height of the WebcamTexture in pixels.                  |
| Rotation  | int                                                                             | Virtual. The frame rotation                                          |

### Example

The example shows how to manage a stream with the `StreamSource` class.

#### Create a StreamSource

To create a `StreamSource`, add a field for Unity to serialize.&#x20;

```csharp
[SerializeField] private StreamSource _stream;
```

#### Get stream information

Get the stream's timestamp, pixels, width, height and rotation.

```csharp
// Get stream timestamp.
DateTime timestamp = _stream.Timestamp;

// Get stream pixels.
Color32[] pixels = _stream.Pixels;

// Get stream width.
int width = _stream.Width;

// Get stream height.
int height = _stream.Height;

// Get stream rotation.
int rotation = _stream.Rotation;
```


# SpriteSource

Manages the sprite functionality.

```csharp
public class SpriteSource : StreamSource
```

Inherits [StreamSource](/ui-reference/streamsource) class.

### Constructors

| Name           | Description                        |
| -------------- | ---------------------------------- |
| SpriteSource() | Creates a new SpriteSource object. |

### Properties

| Name      | Type                                                                            | Description                                                                       |
| --------- | ------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| Timestamp | DateTime                                                                        | Read-Only. Overriden. The frame timestamp.                                        |
| Width     | int                                                                             | Read-Only. Overriden. The width of the sprite texture in pixels.                  |
| Height    | int                                                                             | Read-Only. Overriden. The height of the sprite texture in pixels.                 |
| Pixels    | [UnityEngine.Color32](https://docs.unity3d.com/ScriptReference/Color32.html)\[] | Read-Only. Overriden. The pixel color data for a mipmap level as Color32 structs. |

### Example

The example shows how to manage sprite functionality with the `SpriteSource` class.

#### Create a SpriteSource

To create a `SpriteSource`, add a field for Unity to serialize.&#x20;

```csharp
[SerializeField] private SpriteSource _sprite;
```

#### Get sprite information

Get the sprite's timestamp, pixels, width and height.

```csharp
// Get sprite timestamp.
DateTime timestamp = _sprite.Timestamp;

// Get sprite pixels.
Color32[] pixels = _sprite.Pixels;

// Get sprite width.
int width = _sprite.Width;

// Get sprite height.
int height = _sprite.Height;
```


# VideoSource

Manages the video functionality.

```csharp
public class VideoSource : StreamSource
```

Inherits [StreamSource](/ui-reference/streamsource) class.

### Constructors

| Name          | Description                       |
| ------------- | --------------------------------- |
| VideoSource() | Creates a new VideoSource object. |

### Properties

| Name      | Type                                                                            | Description                                                                       |
| --------- | ------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| Timestamp | DateTime                                                                        | Read-Only. Overriden. The frame timestamp.                                        |
| Width     | int                                                                             | Read-Only. Overriden. The width of the video texture in pixels.                   |
| Height    | int                                                                             | Read-Only. Overriden. The height of the video texture in pixels.                  |
| Pixels    | [UnityEngine.Color32](https://docs.unity3d.com/ScriptReference/Color32.html)\[] | Read-Only. Overriden. The pixel color data for a mipmap level as Color32 structs. |

### Example

The example shows how to manage video functionality with the `VideoSource` class.

#### Create a VideoSource

To create a `VideoSource`, add a field for Unity to serialize.&#x20;

```csharp
[SerializeField] private VideoSource _video;
```

#### Get video information

Get the video's timestamp, pixels, width and height.

```csharp
// Get video timestamp.
DateTime timestamp = _video.Timestamp;

// Get video pixels.
Color32[] pixels = _video.Pixels;

// Get video width.
int width = _video.Width;

// Get video height.
int height = _video.Height;
```


# WebcamSource

Manages the webcam functionality.

```csharp
public class WebcamSource : StreamSource
```

Inherits [StreamSource](/ui-reference/streamsource) class.

### Constructors

| Name           | Description                        |
| -------------- | ---------------------------------- |
| WebcamSource() | Creates a new WebcamSource object. |

### Properties

| Name          | Type                                                                                     | Description                                                                                             |
| ------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| WebcamIndex   | int                                                                                      | Read-Only. The webcam device index.                                                                     |
| WebcamTexture | [UnityEngine.WebCamTexture](https://docs.unity3d.com/ScriptReference/WebCamTexture.html) | Read-Only. The WebcamTexture onto which the live video input is rendered.                               |
| Timestamp     | DateTime                                                                                 | Read-Only. Overriden. The frame timestamp.                                                              |
| IsOpen        | bool                                                                                     | Read-Only. If the camera is currently playing and its Width and Height are greater than 16 pixels each. |
| IsPlaying     | bool                                                                                     | Read-Only. If the camera is currently playing.                                                          |
| Width         | int                                                                                      | Read-Only. Overriden. The width of the WebcamTexture in pixels.                                         |
| Height        | int                                                                                      | Read-Only. Overriden. The height of the WebcamTexture in pixels.                                        |
| Rotation      | int                                                                                      | Read-Only. Overriden. The rotation of the camera.                                                       |
| Pixels        | [UnityEngine.Color32](https://docs.unity3d.com/ScriptReference/Color32.html)\[]          | Read-Only. Overriden. The pixel color data for a mipmap level as Color32 structs.                       |
| Pointer       | IntPtr                                                                                   | Read-Only. Overriden. A native pointer to the WebcamTexture resource.                                   |

### Methods

| Name              | Return Type | Description                                                                  |
| ----------------- | ----------- | ---------------------------------------------------------------------------- |
| Open              | void        | Starts the camera if the app is granted access.                              |
| Close             | void        | Closes the camera.                                                           |
| Pause             | void        | Pauses the camera.                                                           |
| SwitchCamera(int) | void        | Closes the open camera and opens the camera with the specified device index. |

### Example

The example shows how to manage webcam functionality with the `WebcamSource` class.

#### Create a WebcamSource

To create a `Webcam`Source, add a field for Unity to serialize.&#x20;

```csharp
[SerializeField] private WebcamSource _webcam;
```

#### Open webcam

Open the webcam to get the live feed.

```csharp
_webcam.Open();
```

#### Get camera feed

To get the camera feed,  first add an `ImageView` field for Unity to serialize. Then, if the webcam is open and has a new frame, draw the texture.

<pre class="language-csharp"><code class="lang-csharp"><strong>//Create an ImageView
</strong>[SerializeField] private ImageView _image;

// Check if the webcam is open.
if (_webcam.IsOpen)
{
    // Draw the texture for the specified camera.
    _image.Load(_webcam);
}
</code></pre>

#### Close webcam

Close the webcam to stop the live feed.

<pre class="language-csharp"><code class="lang-csharp"><strong>_webcam.Close();
</strong></code></pre>


# HandTrackerExtensions

Extension methods for the StreamSource class.

```csharp
public static class HandTrackerExtensions
```

This is a static class.

### Methods

| Name                                                                                        | Return Type                       | Description                                  |
| ------------------------------------------------------------------------------------------- | --------------------------------- | -------------------------------------------- |
| Load([HandTracker](/api-reference/handtracker), [StreamSource](/ui-reference/streamsource)) | List<[Hand](/api-reference/hand)> | Static. Detects hands in the current stream. |

### Example

The example shows how to detect hands with the `StreamSourceExtensions` class.

#### Detect hands in StreamSource

First, create a [StreamSource](/ui-reference/streamsource) component and a [Handtracker](/api-reference/handtracker) object.

```csharp
[SerializeField] private StreamSource _source;
private readonly HandTracker handTracker = new HandTracker();
```

Then,  use the `HandTrackerExtensions` class to detect hands in the specified [StreamSource](/ui-reference/streamsource).

```csharp
List<Hand> hands = _handTracker.Load(_source);
```


# WebcamSelector

GUI component that switches between cameras.

{% hint style="info" %}
The `WebcamSelector` is a no-code component.
{% endhint %}

```csharp
public class WebcamSelector : MonoBehaviour
```

Inherits [UnityEngine.MonoBehaviour](https://docs.unity3d.com/ScriptReference/MonoBehaviour.html) class.

The `WebcamSelector` is a no-code component that switches between cameras.

### Methods

| Name                  | Return Type | Description                                                                  |
| --------------------- | ----------- | ---------------------------------------------------------------------------- |
| OnWebcamSelected(int) | void        | Closes the open camera and opens the camera with the specified device index. |


